String.prototype.matchAll()
试一试
语法
matchAll(regexp)
参数
regexp
-
一个正则表达式对象,或任何具有
Symbol.matchAll
方法的对象。如果
regexp
不是RegExp
对象,并且没有Symbol.matchAll
方法,则它会使用new RegExp(regexp, 'g')
隐式转换为RegExp
。
返回值
一个 可迭代的迭代器对象(不可重启),包含匹配项,如果未找到匹配项则为空迭代器。迭代器产生的每个值都是一个数组,其形状与 RegExp.prototype.exec()
的返回值相同。
异常
描述
String.prototype.matchAll
的实现本身非常简单 - 它只是简单地调用参数的 Symbol.matchAll
方法,并将字符串作为第一个参数(除了对正则表达式是否为全局进行额外输入验证之外)。实际的实现来自 RegExp.prototype[Symbol.matchAll]()
。
示例
Regexp.prototype.exec() 和 matchAll()
如果没有 matchAll()
,可以使用对 regexp.exec()
(以及带有 g
标志的正则表达式)的调用,并在循环中获取所有匹配项
const 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}.`,
);
}
// Found football start=6 end=14.
// Found foosball start=16 end=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(
`Found ${match[0]} start=${match.index} end=${
match.index + match[0].length
}.`,
);
}
// Found football start=6 end=14.
// 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]);
// [ "football", "foosball" ]
如果缺少 g
标志,matchAll
会抛出异常。
const regexp = /[a-c]/;
const str = "abc";
str.matchAll(regexp);
// TypeError
matchAll
在内部会克隆 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."]]
规范
规范 |
---|
ECMAScript 语言规范 # sec-string.prototype.matchall |
浏览器兼容性
BCD 表格仅在浏览器中加载