試一試
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"]
語法
matchAll(regexp)
引數
regexp-
一個正則表示式物件,或者任何具有
Symbol.matchAll方法的物件。如果
regexp不是RegExp物件且不具有Symbol.matchAll方法,它將透過使用new RegExp(regexp, 'g')被隱式轉換為RegExp。
返回值
一個 可迭代的迭代器物件(不可重新啟動),包含匹配項,或者在未找到匹配項時返回一個空迭代器。迭代器產生的每個值都是一個數組,其形狀與 RegExp.prototype.exec() 的返回值相同。
異常
描述
String.prototype.matchAll 的實現除了對正則表示式是否全域性進行額外輸入驗證之外,主要就是呼叫引數的 Symbol.matchAll 方法,並將字串作為第一個引數傳入。實際的實現來自 RegExp.prototype[Symbol.matchAll]()。
示例
Regexp.prototype.exec() 和 matchAll()
在 matchAll() 出現之前,可以透過在迴圈中使用 regexp.exec() 呼叫(以及設定了 g 標誌的正則表示式)來獲取所有匹配項。
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 迴圈和帶 g 的 exec。取而代之的是,你可以獲取一個迭代器,並使用更方便的 for...of、陣列展開 或 Array.from() 構造。
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 將丟擲異常。
const regexp = /[a-c]/;
const str = "abc";
str.matchAll(regexp);
// TypeError
matchAll 內部會建立一個 regexp 的克隆——因此,與 regexp.exec() 不同,在掃描字串時 lastIndex 不會改變。
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() 時,捕獲組會被忽略。
const regexp = /t(e)(st(\d?))/g;
const str = "test1test2";
str.match(regexp); // ['test1', 'test2']
使用 matchAll,你可以輕鬆訪問捕獲組。
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() 的返回值。
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 |
瀏覽器相容性
載入中…