String.prototype.matchAll()

matchAll()キャプチャグループを含む正規表現に一致するすべての文字列をイテレータで返すメソッドです。

構文

str.matchAll(regexp)

パラメーター

regexp

RegExp オブジェクトです。

正規表現オブジェクトです。正規表現でないオブジェクト obj が渡された場合は new RegExp(obj) を使って RegExp オブジェクトに暗黙的に変換されます。

RegExp オブジェクトにはグローバル(/g)フラグが必須です。フラグがない場合は TypeError が発生します。

戻り値

再起動不可能な イテレータ を返します。

Regexp.exec() と matchAll()

matchAll がJavaScriptに追加される前はループ内でグローバル(/g)フラグを付きのRegExpと regexp.exec を実行することでマッチする全ての結果を取得することができました。

const regexp = 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}.`);
  // expected output: "Found football start=6 end=14."
  // expected output: "Found foosball start=16 end=24."
}

matchAll が使えるようになったことで、 while によるループと、グローバル(/g)フラグ付きの exec を避けることができます。

また代わりに matchAll を使うことで、 for...ofarray spreadArray.from() 構造と効率よく組み合わせることができます。

const regexp = 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}.`);
}
// expected output: "Found football start=6 end=14."
// expected output: "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]);
// Array [ "football", "foosball" ]

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

const regexp = RegExp('[a-c]','');
const str = 'abc';
str.matchAll(regexp);
// TypeError

matchAll では内部的に RegExp オブジェクトをクローンします。そのため regexp.exec() とは違って文字列をスキャンした際に lastIndex が変わることはありません。

const regexp = RegExp('[a-c]','g');
regexp.lastIndex = 1;
const str = 'abc';
Array.from(str.matchAll(regexp), m => `${regexp.lastIndex} ${m[0]}`);
// Array [ "1 b", "1 c" ]

キャプチャリンググループへのより良いアクセス(String.prototype.match()との比較)

matchAll はキャプチャグループへのよりよいアクセスを実現します。

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

let regexp = /t(e)(st(\d?))/g;
let str = 'test1test2';

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

&nbspmatchAllを使えば簡単にキャプチャグループにアクセスできます。

let 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]

仕様

仕様書
ECMAScript (ECMA-262)
String.prototype.matchAll の定義

ブラウザー実装状況

Update compatibility data on GitHub
デスクトップモバイルサーバー
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung InternetNode.js
matchAllChrome 完全対応 73Edge 完全対応 79Firefox 完全対応 67IE 未対応 なしOpera 完全対応 60Safari 完全対応 13WebView Android 完全対応 73Chrome Android 完全対応 73Firefox Android 完全対応 67Opera Android 完全対応 52Safari iOS 完全対応 13Samsung Internet Android 未対応 なしnodejs 完全対応 12.0.0

凡例

完全対応  
完全対応
未対応  
未対応

関連情報