String.prototype.matchAll()

Baseline 已廣泛支援

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

matchAll() 方法用於 String 值,它會返回一個迭代器,該迭代器包含字串與 正則表示式 匹配的所有結果,包括 捕獲組

試一試

const regexp = /t(e)(st(\d?))/g;
const str = "test1test2";

const array = [...str.matchAll(regexp)];

console.log(array[0]);
// Expected output: Array ["test1", "e", "st1", "1"]

console.log(array[1]);
// Expected output: Array ["test2", "e", "st2", "2"]

語法

js
matchAll(regexp)

引數

regexp

一個正則表示式物件,或者任何具有 Symbol.matchAll 方法的物件。

如果 regexp 不是 RegExp 物件且不具有 Symbol.matchAll 方法,它將透過使用 new RegExp(regexp, 'g') 被隱式轉換為 RegExp

如果 regexp 是一個正則表示式,則必須設定全域性 (g) 標誌,否則會丟擲 TypeError

返回值

一個 可迭代的迭代器物件(不可重新啟動),包含匹配項,或者在未找到匹配項時返回一個空迭代器。迭代器產生的每個值都是一個數組,其形狀與 RegExp.prototype.exec() 的返回值相同。

異常

TypeError

如果 regexp 是一個正則表示式 並且沒有設定全域性 (g) 標誌(其 flags 屬性不包含 "g"),則會丟擲此錯誤。

描述

String.prototype.matchAll 的實現除了對正則表示式是否全域性進行額外輸入驗證之外,主要就是呼叫引數的 Symbol.matchAll 方法,並將字串作為第一個引數傳入。實際的實現來自 RegExp.prototype[Symbol.matchAll]()

示例

Regexp.prototype.exec() 和 matchAll()

matchAll() 出現之前,可以透過在迴圈中使用 regexp.exec() 呼叫(以及設定了 g 標誌的正則表示式)來獲取所有匹配項。

js
const regexp = /foo[a-z]*/g;
const str = "table football, foosball";
let match;

while ((match = regexp.exec(str)) !== null) {
  console.log(
    `Found ${match[0]} start=${match.index} end=${regexp.lastIndex}.`,
  );
}
// Found football start=6 end=14.
// Found foosball start=16 end=24.

現在有了 matchAll(),你可以避免使用 while 迴圈和帶 gexec。取而代之的是,你可以獲取一個迭代器,並使用更方便的 for...of陣列展開Array.from() 構造。

js
const regexp = /foo[a-z]*/g;
const str = "table football, foosball";
const matches = str.matchAll(regexp);

for (const match of matches) {
  console.log(
    `Found ${match[0]} start=${match.index} end=${
      match.index + match[0].length
    }.`,
  );
}
// Found football start=6 end=14.
// Found foosball start=16 end=24.

// matches iterator is exhausted after the for...of iteration
// Call matchAll again to create a new iterator
Array.from(str.matchAll(regexp), (m) => m[0]);
// [ "football", "foosball" ]

如果缺少 g 標誌,matchAll 將丟擲異常。

js
const regexp = /[a-c]/;
const str = "abc";
str.matchAll(regexp);
// TypeError

matchAll 內部會建立一個 regexp 的克隆——因此,與 regexp.exec() 不同,在掃描字串時 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" ]

然而,這意味著與在迴圈中使用 regexp.exec() 不同,你無法透過修改 lastIndex 來讓正則表示式前進或後退。

比 String.prototype.match() 更方便地訪問捕獲組

matchAll 另一個引人注目的原因是它改進了對捕獲組的訪問。

當使用帶有全域性 g 標誌的 match() 時,捕獲組會被忽略。

js
const regexp = /t(e)(st(\d?))/g;
const str = "test1test2";

str.match(regexp); // ['test1', 'test2']

使用 matchAll,你可以輕鬆訪問捕獲組。

js
const array = [...str.matchAll(regexp)];

array[0];
// ['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', length: 4]
array[1];
// ['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', length: 4]

將 matchAll() 與實現了 [Symbol.matchAll]() 的非 RegExp 物件一起使用

如果一個物件具有 Symbol.matchAll 方法,它就可以被用作自定義匹配器。Symbol.matchAll 的返回值將成為 matchAll() 的返回值。

js
const str = "Hmm, this is interesting.";

str.matchAll({
  [Symbol.matchAll](str) {
    return [["Yes, it's interesting."]];
  },
}); // returns [["Yes, it's interesting."]]

規範

規範
ECMAScript® 2026 語言規範
# sec-string.prototype.matchall

瀏覽器相容性

另見