Chrome 73 引入了 String.prototype.matchAll()
方法。它的行为与 match()
类似,但会返回一个迭代器,其中包含全局或粘性正则表达式中的所有正则表达式匹配。这样可以轻松迭代匹配项,尤其是当您需要访问捕获组时。
match() 有什么问题?
简短回答是没有任何影响,除非您尝试返回包含捕获组的全局匹配。下面是一个编程题目,供您参考。请考虑以下代码:
const regex = /t(e)(st(\d?))/g;
const string = 'test1test2';
const results = string.match(regex);
console.log(results);
// → ['test1', 'test2']
在控制台中运行此代码,您会发现它会返回一个包含字符串 'test1'
和 'test2'
的数组。如果我从正则表达式中移除 g 标志,则会得到包含所有捕获组的结果,但我只会得到第一个匹配项。如下所示:
['test1', 'e', 'st1', '2', index: 0, input: 'test1test2', groups: undefined]
此字符串包含第二个可能匹配的字符串,以 'test2'
开头,但我没有它。现在,问题来了:如何获取每个匹配项的所有捕获组?“String.prototype.matchAll() 提案”说明介绍了两种可能的方法。我不会详细介绍这些步骤,因为希望您很快就不需要它们了。
String.prototype.matchAll()
matchAll()
的说明示例会是什么样的?看一看就知道了。
const regex = /t(e)(st(\d?))/g;
const string = 'test1test2';
const matches = string.matchAll(regex);
for (const match of matches) {
console.log(match);
}
关于此事,有几点需要注意。与在全局搜索中返回数组的 match()
不同,matchAll()
会返回一个迭代器,该迭代器可与 for...of
循环完美配合使用。迭代器会为每个匹配生成一个数组,包括包含一些附加信息的捕获组。如果您将这些内容输出到控制台,它们将如下所示:
['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', groups: undefined]
['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', groups: undefined]
您可能会注意到,每个匹配项的值都是一个数组,其格式与 match()
针对非全局正则表达式返回的格式完全相同。
奖励内容
本课程主要面向刚接触正则表达式或对正则表达式不熟悉的用户。您可能已经注意到,match() 和 matchAll() 的结果(对于每次迭代)都是包含一些额外命名属性的数组。在准备这篇文章时,我发现 MDN 上对这些属性的文档存在一些缺陷(我已修正)。下面是简要说明。
index
- 原始字符串中第一个结果的索引。在上面的示例中,
test2
从位置 5 开始,因此index
的值为 5。 input
matchAll()
针对其运行的完整字符串。在我的示例中,该值为'test1test2'
。groups
- 包含正则表达式中指定的任何命名捕获组的结果。
总结
如果我遗漏了任何信息,请在下方留言告诉我。如需详细了解 JavaScript 近期的变化,请参阅之前的更新或V8 网站。