String.prototype.matchAll()

如果一个正则表达式在字符串里面有多个匹配,现在一般使用g修饰符或y修饰符,在循环里面逐一取出。

  1. var regex = /t(e)(st(\d?))/g;
  2. var string = 'test1test2test3';
  3. var matches = [];
  4. var match;
  5. while (match = regex.exec(string)) {
  6. matches.push(match);
  7. }
  8. matches
  9. // [
  10. // ["test1", "e", "st1", "1", index: 0, input: "test1test2test3"],
  11. // ["test2", "e", "st2", "2", index: 5, input: "test1test2test3"],
  12. // ["test3", "e", "st3", "3", index: 10, input: "test1test2test3"]
  13. // ]

上面代码中,while循环取出每一轮的正则匹配,一共三轮。

ES2020 增加了String.prototype.matchAll()方法,可以一次性取出所有匹配。不过,它返回的是一个遍历器(Iterator),而不是数组。

  1. const string = 'test1test2test3';
  2. // g 修饰符加不加都可以
  3. const regex = /t(e)(st(\d?))/g;
  4. for (const match of string.matchAll(regex)) {
  5. console.log(match);
  6. }
  7. // ["test1", "e", "st1", "1", index: 0, input: "test1test2test3"]
  8. // ["test2", "e", "st2", "2", index: 5, input: "test1test2test3"]
  9. // ["test3", "e", "st3", "3", index: 10, input: "test1test2test3"]

上面代码中,由于string.matchAll(regex)返回的是遍历器,所以可以用for...of循环取出。相对于返回数组,返回遍历器的好处在于,如果匹配结果是一个很大的数组,那么遍历器比较节省资源。

遍历器转为数组是非常简单的,使用...运算符和Array.from()方法就可以了。

  1. // 转为数组方法一
  2. [...string.matchAll(regex)]
  3. // 转为数组方法二
  4. Array.from(string.matchAll(regex))