String.prototype.matchAll() - JavaScript 编辑
matchAll()
方法返回一个包含所有匹配正则表达式的结果及分组捕获组的迭代器。
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
语法
str.matchAll(regexp)
参数
regexp
正则表达式对象。如果所传参数不是一个正则表达式对象,则会隐式地使用 new RegExp(obj)
将其转换为一个 RegExp
。
RegExp
必须是设置了全局模式g
的形式,否则会抛出异常TypeError
。
返回值
一个迭代器(不可重用,结果耗尽需要再次调用方法,获取一个新的迭代器)。
例子
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, 或者 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]);
// TypeError: String.prototype.matchAll called with a non-global RegExp argument
matchAll
内部做了一个 regexp 的复制,所以不像 regexp.exec, lastIndex
在字符串扫描时不会改变。
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 (ECMA-262) String.prototype.matchAll | Living Standard |
浏览器兼容性
BCD tables only load in the browser
The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.
相关链接
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论