Skip to content

Commit a7ce045

Browse files
authored
Add matchAll() article. (google#7171)
* Add matchAll() article. * Forgot to commit error fixes. * Fix closing tag. * Fix other closing tag. Grrr! * Fixes
1 parent b715188 commit a7ce045

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
project_path: /web/_project.yaml
2+
book_path: /web/updates/_book.yaml
3+
description: Chrome 73 introduces the String.prototype.matchAll() method. It behaves similarly to match(), but offers a simple way to iterate over matches, especially when you need access to capture groups.
4+
5+
{# wf_published_on: 2019-02-07 #}
6+
{# wf_updated_on: 2019-01-30 #}
7+
{# wf_featured_image: /web/updates/images/generic/js.png #}
8+
{# wf_tags: chrome73,javascript,regex #}
9+
{# wf_featured_snippet: Chrome 73 introduces the <code>String.prototype.matchAll()</code> method. It behaves similarly to <code>match()</code>, but offers a simple way to iterate over matches, especially when you need access to capture groups. #}
10+
{# wf_blink_components: Blink>JavaScript>Language #}
11+
12+
# Better match results with String.prototype.matchAll() {: .page-title }
13+
14+
{% include "web/_shared/contributors/josephmedley.html" %}
15+
16+
Chrome 73 introduces the `String.prototype.matchAll()` method. It behaves
17+
similarly to `match()`, but returns an iterator with all regular expression
18+
matches in a global or sticky regular expression. This offers a simple way to
19+
iterate over matches, especially when you need access to capture groups.
20+
21+
## What's wrong with match()?
22+
23+
The short answer is nothing, unless you're trying to return global matches with
24+
capturing groups. Here's a programming puzzle for you. Consider the following
25+
code:
26+
27+
```js
28+
const regex = /t(e)(st(\d?))/g;
29+
const string = 'test1test2';
30+
const results = string.match(regex);
31+
console.log(results);
32+
// → ['test1', 'test2']
33+
```
34+
35+
Run this in a console and notice that it returns an array containing the
36+
strings `'test1'` and `'test2'`. If I remove the g flag from the regular
37+
expression what I get has all of my capturing groups, but I only get the first
38+
match. It looks like this:
39+
40+
```js
41+
['test1', 'e', 'st1', '2', index: 0, input: 'test1test2', groups: undefined]
42+
```
43+
44+
This string contains a second possible match beginning with `'test2'` but I don't
45+
have it. Now here's the puzzle: how do I get all of the capturing groups for
46+
each match? The [explainer for the String.prototype.matchAll()
47+
proposal](https://github.com/tc39/proposal-string-matchall)
48+
shows two possible approaches. I won't describe them because hopefully you
49+
won't need them much longer.
50+
51+
## String.prototype.matchAll()
52+
53+
What would the explainer examples look like with `matchAll()`? Have a look.
54+
55+
```js
56+
const regex = /t(e)(st(\d?))/g;
57+
const string = 'test1test2';
58+
const matches = string.matchAll(regex);
59+
for (const match of matches) {
60+
console.log(match);
61+
}
62+
```
63+
64+
There are a few things to note about this. Unlike `match()` which returns an
65+
array on a global search, `matchAll()` returns an iterable object that works
66+
beautifully with `for...of` loops. The iterable object produces an array for
67+
each match, including the capturing groups with a few extras. If you print
68+
these to the console they'll look like this:
69+
70+
```js
71+
['test1', 'e', 'st1', '2', index: 0, input: 'test1test2', groups: undefined]
72+
['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', groups: undefined]
73+
```
74+
75+
You may notice that the value for each match is an array in exactly the same
76+
format returned by `match()` for non-global regular expressions.
77+
78+
## Bonus material
79+
80+
This is mainly for people who are new to regular expressions or who aren't
81+
experts at it. You may have noticed the results of both match() and matchAll()
82+
(for each iteration) are arrays with some additional named properties. While
83+
preparing this article, I noticed that these properties have some documentation
84+
deficiencies on MDN (which
85+
[I've fixed](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match#Return_value)).
86+
Here's a quick description.
87+
88+
<dl>
89+
<dt><code>index</code></dt>
90+
<dd>The index of the first result in the original string. In the above example <code>test2</code> starts at position 5 hence <code>index</code> has the value 5.</dd>
91+
<dt><code>input</code></dt>
92+
<dd>The complete string that <code>matchAll()</code> was run against. In my example, that was <code>'test1test2'</code>.</dd>
93+
<dt><code>groups</code></dt>
94+
<dd>Contains the results of any <a href='https://mathiasbynens.be/notes/es-regexp-proposals#named-capture-groups'>named capturing
95+
groups</a> specified in your regular expression.</dd>
96+
</dl>
97+
98+
## Conclusion
99+
100+
If I've missed anything please let me know in the comments below. You can read more about recent changes to JavaScript [in previous
101+
updates](/web/updates/tags/javascript) or on [the V8 website](https://v8.dev/).
102+
103+
{% include "web/_shared/helpful.html" %}
104+
105+
{% include "web/_shared/rss-widget-updates.html" %}

0 commit comments

Comments
 (0)