在以往的 ES6
和 ES7
中,我们可以通过 String.prototype.match()
方法来实现字符串匹配的功能,但是这个方法只适用于匹配单个目标,而不能做到全局匹配。在 ES8
中,String.prototype.matchAll()
方法被引入,可以很方便的解决全局匹配的问题。
String.prototype.matchAll() 方法
String.prototype.matchAll()
是在 ES10
中被引入的,作用是执行全局正则表达式匹配,并返回一个匹配结果的迭代器。这个新函数可以匹配所有目标,且可以遍历所有匹配结果。
该方法接受一个正则表达式参数,并返回一个匹配结果的迭代器。如果迭代器已经迭代完毕,那么它的 done
属性将变为 true
,否则返回一个包含匹配结果的对象,其中包含了这个匹配的属性,作为键值对。
下面是一个例子,通过正则表达式匹配出一个字符串中所有的电话号码并打印出来:
const regex = /(\d{3})-(\d{3})-(\d{4})/g; const str = 'Tel: 123-456-7890, Mobile: 456-789-1234'; const matches = str.matchAll(regex); for (const match of matches) { console.log(match[0] + ' ' + match[1]); }
这个例子中,我们使用了正则表达式 /(\d{3})-(\d{3})-(\d{4})/g
来匹配我们的字符串。g
标志表示全局匹配。然后,我们将结果迭代并输出。
输出结果:
123-456-7890 123 456-789-1234 456
可以看出输出结果已经匹配到了所有的电话号码,并通过 match[0]
获取了完整的电话号码并通过 match[1]
获取了每个号码的前三位。
使用 String.prototype.match() 的问题
String.prototype.match()
方法是我们以往常用的字符串匹配方法,返回的结果是匹配到的字符串数组,但它只能匹配字符串中第一个匹配的目标,如果要匹配所有的目标,我们需要在正则表达式中加入全局标志 g
:
const str = 'Foo foo bar foo'; const regex = /foo/g; const results = str.match(regex) console.log(results); // ["foo", "foo", "foo"]
可以看到,使用 g
标志后,我们可以匹配到所有的目标。
但是,这种方法存在一些不便之处。
首先,match()
返回的是一个数组,无法迭代,因此我们需要使用 forEach()
或者 for...of
循环遍历。
其次,当我们需要遍历字符串并匹配多个正则表达式时,我们需要针对每个表达式进行多次调用,这会降低代码的效率。
最后,match()
方法并未提供对于匹配属性的访问,而 matchAll()
可以在匹配结果中提供匹配属性的访问方式。
总结
String.prototype.matchAll()
是一个很有用的功能,可以很方便地在一个字符串中匹配多个正则表达式,并可以遍历所有匹配结果。相对于 match()
方法,它提供了更好的迭代机制和属性访问功能,更加适合在 JavaScript 中使用。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64bfd3269e06631ab9c5004e