String.prototype.matchAll()

matchAll() 方法返回一个包含所有匹配正则表达式的结果及分组捕获组的迭代器。

语法

str.matchAll(regexp)

参数

regexp

    正则表达式对象。如果所传参数不是一个正则表达式对象,则会隐式地使用 new RegExp(obj) 将其转换为一个 RegExp 。

返回值

一个迭代器(不可重用,结果耗尽需要再次调用方法,获取一个新的迭代器)。

例子

Regexp.exec() 和 matchAll()

matchAll 出现之前,通过在循环中调用regexp.exec来获取所有匹配项信息(regexp需使用/g标志):

const regexp = RegExp('foo[a-z]*','g');
const str = 'table football, foosball';
let match;

while ((match = regexp.exec(str)) !== null) {
  console.log(`Found ${match[0]} start=${match.index} end=${regexp.lastIndex}.`);
  // expected output: "Found football start=6 end=14."
  // expected output: "Found foosball start=16 end=24."
}

如果使用matchAll ,就可以不必使用while循环加exec方式(且正则表达式需使用/g标志)。使用matchAll 会得到一个迭代器的返回值,配合 for...of, array spread, or Array.from() 可以更方便实现功能:

const regexp = RegExp('foo[a-z]*','g');
const str = 'table football, foosball';
const matches = str.matchAll(regexp);

for (const match of matches) {
  console.log(`Found ${match[0]} start=${match.index} end=${match.index + match[0].length}.`);
}
// expected output: "Found football start=6 end=14."
// expected output: "Found foosball start=16 end=24."

// matches iterator is exhausted after the for..of iteration
// Call matchAll again to create a new iterator
Array.from(str.matchAll(regexp), m => m[0]);
// Array [ "football", "foosball" ]

如果没有 /g 标志则matchAll 只会返回首个匹配。

const regexp = RegExp('[a-c]','');
const str = 'abc';
Array.from(str.matchAll(regexp), m => m[0]);
// Array [ "a" ]

matchAll 内部做了一个regexp的复制,所以不像 regexp.execlastIndex 在字符串扫描时不会改变。

const regexp = RegExp('[a-c]','g');
regexp.lastIndex = 1;
const str = 'abc';
Array.from(str.matchAll(regexp), m => `${regexp.lastIndex} ${m[0]}`);
// Array [ "1 b", "1 c" ]

捕获组的更佳途径

matchAll 的另外一个亮点是更好地获取捕获组。因为当使用match()和/g标志方式获取匹配信息时,捕获组会被忽略:

var regexp = /t(e)(st(\d?))/g;
var str = 'test1test2';

str.match(regexp); 
// Array ['test1', 'test2']

使用 matchAll 可以通过如下方式获取分组捕获:

let array = [...str.matchAll(regexp)];

array[0];
// ['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', length: 4]
array[1];
// ['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', length: 4]

规范

Specification Status
ECMAScript Latest Draft (ECMA-262)
String.prototype.matchAll
Draft

浏览器兼容性

Update compatibility data on GitHub
Desktop Mobile Server
Chrome Edge Firefox Internet Explorer Opera Safari Android webview Chrome for Android Firefox for Android Opera for Android Safari on iOS Samsung Internet Node.js
matchAll Chrome Full support 73 Edge No support No Firefox Full support 67 IE No support No Opera Full support 60 Safari No support No WebView Android Full support 73 Chrome Android Full support 73 Firefox Android Full support 67 Opera Android Full support Yes Safari iOS No support No Samsung Internet Android No support No nodejs Full support 12.0.0

Legend

Full support  
Full support
No support  
No support

相关链接