Chrome 73 推出 String.prototype.matchAll()
方法。它的行為類似於 match()
,但會傳回迭代器,其中包含全域或黏性規則運算式中的所有規則運算式比對結果。這可提供簡單的方法,讓您重複執行相符項目,特別是在需要存取擷取群組時。
match() 有什麼問題?
簡單來說,除非您嘗試使用擷取群組傳回全域比對結果,否則不需要。以下是程式設計謎題,請考慮使用以下程式碼:
const regex = /t(e)(st(\d?))/g;
const string = 'test1test2';
const results = string.match(regex);
console.log(results);
// → ['test1', 'test2']
在控制台中執行這段程式碼,您會發現它會傳回包含字串 'test1'
和 'test2'
的陣列。如果從規則運算式中移除 g 標記,我會取得所有擷取群組,但只會取得第一個相符項目。這是訂閱按鈕的圖示:
['test1', 'e', 'st1', '2', index: 0, input: 'test1test2', groups: undefined]
這個字串包含第二個可能的 'test2'
開頭比對結果,但我沒有這個字串。接下來是謎題:如何取得每個相符項目的所有擷取群組?String.prototype.matchAll() 提案的說明說明瞭兩種可能的方法。我不會描述這些內容,因為希望您很快就不需要這些內容。
String.prototype.matchAll()
matchAll()
的說明範例會是什麼樣子?瞧一眼吧。
const regex = /t(e)(st(\d?))/g;
const string = 'test1test2';
const matches = string.matchAll(regex);
for (const match of matches) {
console.log(match);
}
這裡有幾點需要注意。match()
會在全域搜尋中傳回陣列,而 matchAll()
會傳回迭代器,可與 for...of
迴圈完美搭配運作。迭代器會為每個比對結果產生陣列,包括擷取群組和一些額外項目。如果您將這些內容列印到控制台中,它們會如下所示:
['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', groups: undefined]
['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', groups: undefined]
您可能會注意到,每個比對的值都是陣列,格式與 match()
針對非全域規則運算式傳回的格式完全相同。
額外內容
這篇文章主要適用於不熟悉或不擅長正規表示式的使用者。您可能會注意到,match() 和 matchAll() 的結果 (針對每個迭代) 都是陣列,其中包含一些額外的命名屬性。在準備這篇文章時,我發現這些屬性在 MDN 上有某些文件缺失情形 (我已修正)。以下簡要說明。
index
- 原始字串中第一個結果的索引。在上述範例中,
test2
從第 5 個位置開始,因此index
的值為 5。 input
- 系統執行
matchAll()
的完整字串。在我的範例中,這個值是'test1test2'
。 groups
- 包含規則運算式中指定的任何命名擷取群組結果。
結論
如果我遺漏了任何內容,請在下方留言告訴我。如要進一步瞭解 JavaScript 的近期變更,請參閱先前的更新或V8 網站。