在 ES11 中,引入了一种新的内置方法:String.prototype.matchAll()
,这个方法可以让你在字符串中进行全局匹配,且返回一个可以遍历所有匹配结果的迭代器对象。本文将详细介绍 matchAll()
的使用,并给出一些实用的例子。
接口介绍
String.prototype.matchAll()
方法返回一个包含所有匹配的迭代器对象,该迭代器对象可以遍历所有匹配项,并且可以访问每个匹配项正则表达式捕获的所有分组信息。matchAll()
参数是一个正则表达式,返回一个迭代器对象,可以通过 next()
方法遍历所有匹配项。
该方法的语法如下:
string.matchAll(regexp);
其中 string
是要进行匹配的字符串,regexp
是一个正则表达式,表示要匹配的模式。
如果没有找到任何匹配,则返回的迭代器对象的 done
属性值为 true
。
使用示例
下面是一个简单的 matchAll()
示例,它展示了如何使用迭代器对象遍历所有匹配项:
const str = 'The quick brown fox jumps over the lazy dog.'; const regexp = /the/gi; const matches = str.matchAll(regexp); for (const match of matches) { console.log(match); }
在这个示例中,我们定义了一个字符串 str
,并通过正则表达式 regexp
进行匹配。然后调用 matchAll()
方法,遍历每个匹配项,并将其打印到控制台中。
输出结果如下:
["The", index: 0, input: "The quick brown fox jumps over the lazy dog.", groups: undefined] ["the", index: 31, input: "The quick brown fox jumps over the lazy dog.", groups: undefined] ["the", index: 38, input: "The quick brown fox jumps over the lazy dog.", groups: undefined]
在输出结果中,每个元素都是一个 배열,包含匹配的字符串,它的索引和输入字符串,以及任何捕获分组信息。
如果要确定 matchAll()
方法是否找到了匹配项,可以检查迭代器对象的 done
属性值。
if (matches.done) { console.log('No matches were found.'); }
高级用法
除了基本用法外,matchAll()
方法还有一些高级用法,例如在正则表达式中使用具名分组,以及使用零宽度断言。
使用具名分组
在正则表达式中使用具名分组,可以用于提取字符串中特定部分的信息。具名分组是指以 (?<group_name>pattern)
的形式定义的分组。
下面是一个具名分组示例:
const str = '2020-01-01, 2021-02-02, 2022-03-03'; const regexp = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/g; const matches = str.matchAll(regexp); for (const match of matches) { console.log(match.groups); }
在这个示例中,我们使用正则表达式提取字符串中的日期,并使用具名分组将其拆分为年、月和日。然后使用迭代器对象遍历所有匹配项,并将捕获的分组信息打印到控制台中。
输出结果如下:
{year: "2020", month: "01", day: "01"} {year: "2021", month: "02", day: "02"} {year: "2022", month: "03", day: "03"}
在输出结果中,我们可以看到每个匹配项的 groups
属性值是一个对象,包含了具名分组捕获的信息。
使用零宽度断言
在正则表达式中,零宽度断言用于定义匹配项的边界,而不是将它们包含在匹配的结果中。使用零宽度断言可以提高正则表达式的效率,同时也可以更精确地匹配字符串。
下面是一个使用零宽度断言的示例:
const str = '2020 01 01 2021 02 02 2022 03 03'; const regexp = /(?<=\d{4}\s)(\d{2})|(?<=\s\d{2}\s)(\d{2})/g; const matches = str.matchAll(regexp); for (const match of matches) { console.log(match[0]); }
在这个示例中,我们使用正则表达式匹配字符串中的日期,并使用零宽度断言提高匹配效率。具体来说,我们使用 (?<=\d{4}\s)
定义了一个肯定的后行断言,表示匹配一个四位数的年份后面的空格,然后捕获两位数的月份。同样地,我们使用 (?<=\s\d{2}\s)
定义了另一个后行断言,表示匹配一个空格后面的两位数天数,然后捕获两位数的月份。
输出结果如下:
01 02 03 01 02 03
在输出结果中,我们可以看到在使用零宽度断言的情况下,正则表达式只匹配了月份,而没有匹配年份或天数。
总结
在本文中,我们介绍了 JavaScript ES11 中的 String.prototype.matchAll()
方法。我们学习了如何使用迭代器对象遍历字符串中的所有匹配项,以及如何使用具名分组和零宽度断言进行高级匹配。希望这篇文章对您学习 JavaScript 的正则表达式有所帮助。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/648a514148841e9894878b93