RegExp.prototype[Symbol.matchAll]()

Baseline 已廣泛支援

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2020 年 1 月⁩ 起,所有主流瀏覽器均已支援。

[Symbol.matchAll]() 方法在 RegExp 例項上,用於指定 String.prototype.matchAll 的行為。

試一試

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

const re = new MyRegExp("-\\d+", "g");
console.log("2016-01-02|2019-03-07".matchAll(re));
// Expected output: Array [Array ["-01"], Array ["-02"], Array ["-03"], Array ["-07"]]

語法

js
regexp[Symbol.matchAll](str)

引數

str

一個作為匹配目標的 String

返回值

一個匹配項的 可迭代迭代器物件(不可重置)。每個匹配項都是一個數組,其形狀與 RegExp.prototype.exec() 的返回值相同。

描述

此方法在內部由 String.prototype.matchAll() 呼叫。例如,以下兩個示例返回相同的結果。

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

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

[Symbol.split]() 類似,[Symbol.matchAll]() 首先使用 [Symbol.species] 構建一個新的正則表示式,從而避免以任何方式修改原始正則表示式。lastIndex 的初始值是原始正則表示式的值。

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() 並生成結果。

當正則表示式是粘性的(sticky)且全域性時,它仍然會執行粘性匹配——也就是說,它不會匹配 lastIndex 之外的任何出現。

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

如果當前匹配項是空字串,則 lastIndex 仍會推進。如果正則表示式具有 u 標誌,則它會推進一個 Unicode 程式碼點;否則,它會推進一個 UTF-16 程式碼點。

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

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

此方法用於自定義 RegExp 子類中 matchAll() 的行為。

示例

直接呼叫

此方法的使用方式與 String.prototype.matchAll() 幾乎相同,只是 this 的值和引數的順序不同。

js
const re = /\d+/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]()

RegExp 的子類可以重寫 [Symbol.matchAll]() 方法來修改預設行為。

例如,要返回一個 Array 而不是一個 迭代器

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("(\\d+)-(\\d+)-(\\d+)", "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" ]

規範

規範
ECMAScript® 2026 語言規範
# sec-regexp-prototype-%symbol.matchall%

瀏覽器相容性

另見