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'
で始まる 2 番目の一致が含まれていますが、この文字列は含まれていません。問題は、各一致のすべてのキャプチャ グループを取得する方法です。String.prototype.matchAll() プロポーザルの説明では、考えられる 2 つのアプローチを示しています。今後は必要なくなることを願って、詳細は説明しません。
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 ウェブサイトをご覧ください。