此页面由社区从英文翻译而来。了解更多并加入 MDN Web Docs 社区。
String.prototype.matchAll()
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2020年1月.
In this article
尝试一下
const regexp = /t(e)(st(\d?))/g;const str = "test1test2";const array = [...str.matchAll(regexp)];console.log(array[0]);// Expected output: Array ["test1", "e", "st1", "1"]console.log(array[1]);// Expected output: Array ["test2", "e", "st2", "2"]语法
matchAll(regexp)参数
regexp一个正则表达式对象,或者是任何具有
Symbol.matchAll方法的对象。如果
regexp不是一个RegExp对象,并且没有Symbol.matchAll方法,它将通过new RegExp(regexp, 'g')被隐式转换为一个RegExp对象。
返回值
一个匹配结果的可迭代迭代器对象(它不可重新开始)。每个匹配结果都是一个数组,其形状与RegExp.prototype.exec() 的返回值相同。
异常
描述
String.prototype.matchAll 方法本身的实现非常简单,它只是调用了参数的Symbol.matchAll 方法,并将字符串作为第一个参数传递了进去(除了额外的输入验证,即正则表达式必须是全局的)。实际的实现来自RegExp.prototypeSymbol.matchAll]()。
示例
>Regexp.prototype.exec() 和 matchAll()
如果没有matchAll() 方法,仍然可以使用带有g 标志的正则表达式调用regexp.exec() 来在循环中获取所有匹配结果:
const regexp = /foo[a-z]*/g;const str = "table football, foosball";let match;while ((match = regexp.exec(str)) !== null) { console.log( `找到 ${match[0]} 起始位置=${match.index} 结束位置=${regexp.lastIndex}。`, );}// 找到 football 起始位置=6 结束位置=14。// 找到 foosball 起始位置=16 结束位置=24。如果有matchAll() 方法,则可以避免使用while 循环和带有g 标志的exec。相反,你可以获得一个迭代器,以便使用更方便的for...of 循环、数组展开语法或Array.from() 构造函数:
const regexp = /foo[a-z]*/g;const str = "table football, foosball";const matches = str.matchAll(regexp);for (const match of matches) { console.log( `找到 ${match[0]} 起始位置=${match.index} 结束位置=${ match.index + match[0].length }.`, );}// 找到 football 起始位置=6 结束位置=14.// 找到 foosball 起始位置=16 结束位置=24.// 匹配迭代器在 for...of 迭代后用尽// 再次调用 matchAll 以创建新的迭代器Array.from(str.matchAll(regexp), (m) => m[0]);// [ "football", "foosball" ]如果没有g 标志,matchAll 会抛出异常。
const regexp = /[a-c]/;const str = "abc";str.matchAll(regexp);// TypeErrormatchAll 内部做了一个regexp 的复制,所以不像regexp.exec(),lastIndex 在字符串扫描后不会改变。
const regexp = /[a-c]/g;regexp.lastIndex = 1;const str = "abc";Array.from(str.matchAll(regexp), (m) => `${regexp.lastIndex} ${m[0]}`);// [ "1 b", "1 c" ]然而,这也意味着,与在循环中使用regexp.exec() 不同,你不能更改lastIndex 来使正则表达式前进或倒退。
比 String.prototype.match() 更好的捕获组获取方式
matchAll() 方法的另一个重要优点是改进了对于捕获组的获取方式。
当使用全局g 标志调用match() 方法时,捕获组会被忽略:
const regexp = /t(e)(st(\d?))/g;const str = "test1test2";str.match(regexp); // ['test1', 'test2']使用matchAll 方法,可以轻松获取捕获组:
const 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]使用实现了[Symbol.matchAll]() 的非正则对象调用 matchAll()
如果一个对象有一个Symbol.matchAll 方法,它可以被用作自定义匹配器。Symbol.matchAll 的返回值将成为matchAll() 的返回值。
const str = "Hmm, this is interesting.";str.matchAll({ [Symbol.matchAll](str) { return [["Yes, it's interesting."]]; },}); // returns [["Yes, it's interesting."]]规范
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-string.prototype.matchall> |