RegExp.prototype[Symbol.matchAll]()

RegExp 实例的 [Symbol.matchAll]() 方法指定 String.prototype.matchAll 的行为方式。

¥The [Symbol.matchAll]() method of RegExp instances specifies how String.prototype.matchAll should behave.

Try it

语法

¥Syntax

js
regexp[Symbol.matchAll](str)

参数

¥Parameters

str

作为比赛目标的 String

返回值

¥Return value

可迭代的迭代器对象(不可重新开始)比赛。每个匹配都是一个与 RegExp.prototype.exec() 的返回值形状相同的数组。

¥An iterable iterator object (which is not restartable) of matches. Each match is an array with the same shape as the return value of RegExp.prototype.exec().

描述

¥Description

该方法在 String.prototype.matchAll() 内部被调用。例如,以下两个示例返回相同的结果。

¥This method is called internally in String.prototype.matchAll(). For example, the following two examples return the same result.

js
"abc".matchAll(/a/g);

/a/g[Symbol.matchAll]("abc");

[Symbol.split]() 一样,[Symbol.matchAll]() 首先使用 [Symbol.species] 构造一个新的正则表达式,从而避免以任何方式改变原始正则表达式。lastIndex 作为原始正则表达式的值开始。

¥Like [Symbol.split](), [Symbol.matchAll]() starts by using [Symbol.species] to construct a new regex, thus avoiding mutating the original regexp in any way. lastIndex starts as the original regex's value.

js
const regexp = /[a-c]/g;
regexp.lastIndex = 1;
const str = "abc";
Array.from(str.matchAll(regexp), (m) => `${regexp.lastIndex} ${m[0]}`);
// [ "1 b", "1 c" ]

输入是全局正则表达式的验证发生在 String.prototype.matchAll() 中。[Symbol.matchAll]() 不验证输入。如果正则表达式不是全局的,则返回的迭代器将产生 exec() 结果一次,然后返回 undefined。如果正则表达式是全局的,则每次调用返回的迭代器的 next() 方法时,都会调用正则表达式的 exec() 并产生结果。

¥The validation that the input is a global regex happens in String.prototype.matchAll(). [Symbol.matchAll]() does not validate the input. If the regex is not global, the returned iterator yields the exec() result once and then returns undefined. If the regexp is global, each time the returned iterator's next() method is called, the regex's exec() is called and the result is yielded.

当正则表达式是粘性和全局的时,它仍然会执行粘性匹配 - 即它不会匹配 lastIndex 之外的任何匹配项。

¥When the regex is sticky and global, it will still perform sticky matches — i.e. it will not match any occurrences beyond the lastIndex.

js
console.log(Array.from("ab-c".matchAll(/[abc]/gy)));
// [ [ "a" ], [ "b" ] ]

如果当前匹配是空字符串,则 lastIndex 仍会前进。如果正则表达式具有 u 标志,则它前进一个 Unicode 代码点;否则,它前进一个 UTF-16 代码点。

¥If the current match is an empty string, the lastIndex will still be advanced. If the regex has the u flag, it advances by one Unicode code point; otherwise, it advances by one UTF-16 code point.

js
console.log(Array.from("😄".matchAll(/(?:)/g)));
// [ [ "" ], [ "" ], [ "" ] ]

console.log(Array.from("😄".matchAll(/(?:)/gu)));
// [ [ "" ], [ "" ] ]

该方法用于自定义 RegExp 子类中 matchAll() 的行为。

¥This method exists for customizing the behavior of matchAll() in RegExp subclasses.

示例

¥Examples

直接致电

¥Direct call

该方法的使用方式与 String.prototype.matchAll() 几乎相同,除了 this 的值不同以及参数的顺序不同之外。

¥This method can be used in almost the same way as String.prototype.matchAll(), except for the different value of this and the different order of arguments.

js
const re = /[0-9]+/g;
const str = "2016-01-02";
const result = re[Symbol.matchAll](str);

console.log(Array.from(result, (x) => x[0]));
// [ "2016", "01", "02" ]

在子类中使用 [Symbol.matchAll]()

¥Using [Symbol.matchAll]() in subclasses

RegExp 的子类可以重写 [Symbol.matchAll]() 方法来修改默认行为。

¥Subclasses of RegExp can override the [Symbol.matchAll]() method to modify the default behavior.

例如,要返回 Array 而不是 iterator

¥For example, to return an Array instead of an iterator:

js
class MyRegExp extends RegExp {
  [Symbol.matchAll](str) {
    const result = RegExp.prototype[Symbol.matchAll].call(this, str);
    return result ? Array.from(result) : null;
  }
}

const re = new MyRegExp("([0-9]+)-([0-9]+)-([0-9]+)", "g");
const str = "2016-01-02|2019-03-07";
const result = str.matchAll(re);

console.log(result[0]);
// [ "2016-01-02", "2016", "01", "02" ]

console.log(result[1]);
// [ "2019-03-07", "2019", "03", "07" ]

规范

Specification
ECMAScript Language Specification
# sec-regexp-prototype-matchall

¥Specifications

浏览器兼容性

BCD tables only load in the browser

¥Browser compatibility

也可以看看