← 返回首页
String.prototype.matchAll() - JavaScript | MDN

このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docs コミュニティーについてもっと知り、仲間になるにはこちらから。

View in English Always switch to English

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]); // 予想される結果: Array ["test1", "e", "st1", "1"] console.log(array[1]); // 予想される結果: Array ["test2", "e", "st2", "2"]

構文

js
matchAll(regexp)

引数

regexp

正規表現オブジェクト、または Symbol.matchAll を持つ任意のオブジェクトです。

regexp が RegExp 以外のオブジェクトであった場合、暗黙的に RegExp への変換が new RegExp(regexp, 'g') を使用して行われます。

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() が JavaScript に追加される前は、 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 によるループと、g 付きの exec を避けることができます。代わりにイテレーターが取得できるので、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. // 一致したイテレーターは for...of の反復処理の後で利用不可になる // 新しいイテレーターを作成するために matchAll を再度呼び出す Array.from(str.matchAll(regexp), (m) => m[0]); // [ "football", "foosball" ]

matchAll は、グローバル (g) フラグがない場合は例外が発生します。

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 はキャプチャグループへのよりよいアクセスを実現します。

match() では、グローバル g フラグを使用するとキャプチャグループが無視されてしまいます。

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() を RegExp ではない [Symbol.matchAll]() を実装しているオブジェクトで使用

オブジェクトに Symbol.matchAll メソッドがあれば、それをカスタムマッチャーとして使うことができます。Symbol.matchAll の返値は matchAll() の返値となる。

js
const str = "Hmm, this is interesting."; str.matchAll({ [Symbol.matchAll](str) { return [["Yes, it's interesting."]]; }, }); // [["Yes, it's interesting."]] を返す

仕様書

仕様書
ECMAScript® 2027 Language Specification
# sec-string.prototype.matchall

ブラウザーの互換性

ブラウザー互換性一覧表を表示するには、JavaScript を有効にしてください。

関連情報