为什么JavaScript中的RegExp的matchAll与其他方法如此不同?

时间:2019-06-23 14:46:34

标签: javascript

JavaScript具有正则表达式类RegExp。您可以直接创建re = new RegExp(...)或间接创建re = /.../

大多数传统方法都是我多年编程所惯用的

const match = re.match(str);
const isMatch = re.text(str);

但是今天我寻找了matchAll函数,使用它的语法是这样

const matches = re[Symbol.matchAll](str)

这种查找功能的方式是怎么回事?为什么不只是

const matches = re.matchAll(str);

我猜测是由于某些原因使用此特殊格式的某些功能。背后的原因是什么?

const re = /a(.)b(.)c/g;
const matches = re[Symbol.matchAll]('a1b2c a3b4c a5b6c');
console.log([...matches]);

1 个答案:

答案 0 :(得分:2)

  

我寻找了matchAll函数,使用它的语法为re[Symbol.matchAll](str)

不。正确的语法是使用String matchAll method,如下所示:

const matches = str.matchAll(re);
  

使用这种特殊格式的几种功能背后的原因是什么?

他们遵循的是协议。像iterable protocolthenable protocol一样,它们通常在其他一些方法/语法中内部使用,因此不应直接调用。这种协议允许自定义功能的实现,从而提供了一个覆盖的钩子。

对于Symbol.matchAll,它允许将任意对象用作字符串的匹配器。例如:

const integers = {
    *[Symbol.matchAll] (str) {
         for (const m of str.matchAll(/\d+/g))
             yield parseInt(m[0], 10);
    }
};

console.log(Array.from("42ab17, 2x".matchAll(integers)))

引入了matchAllmatch符号,以使class的{​​{1}}可以在与相应的extends RegExp方法进行交互时覆盖行为。在实践中,虽然不强制执行继承关系,仅存在符号键方法就足够了。