首页 > 解决方案 > 为什么 JavaScript 中 RegExp 的 matchAll 与其他方法如此不同?

问题描述

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]);

标签: javascript

解决方案


我寻找了一个 matchAll 函数并使用它的语法是re[Symbol.matchAll](str)

不,正确的语法是使用StringmatchAll方法,如下所示:

const matches = str.matchAll(re);

使用这种特殊格式的几个函数背后的原因是什么?

他们遵循一个协议。像iterable 协议thenable 协议一样,它们通常在内部用于一些其他方法/语法,不应该直接调用。这样的协议允许自定义特性的实现,提供一个覆盖的钩子。

在 的情况下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)))

matchAll引入和match符号是为了允许在与相应方法交互class时覆盖行为。实际上,继承关系并没有被强制执行,仅仅存在符号键控方法就足够了。extends RegExpString


推荐阅读