RegExp.prototype[Symbol.matchAll]()
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
[Symbol.match]()
は RegExp
インスタンスのメソッドで、 String.prototype.matchAll
がどのように動作するのかを指定します。
試してみましょう
構文
regexp[Symbol.matchAll](str)
引数
返値
一致したものを表す反復可能なイテレーターオブジェクト(再起動不可)です。それぞれの一致部分は RegExp.prototype.exec()
の返値と同じ形の配列です。
解説
このメソッドは内部的に String.prototype.matchAll()
を呼び出します。例えば、以下の 2 つの例は同じ結果を返します。
"abc".matchAll(/a/g);
/a/g[Symbol.matchAll]("abc");
Symbol.split
と同様、 [Symbol.matchAll]()
は Symbol.species
を使用して新しい正規表現を作成するところから始め、何があっても元の正規表現を変更することを避けます。 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" ]
入力がグローバル正規表現であるかどうかの検証は String.prototype.matchAll()
で行われます。[Symbol.matchAll]()
は入力を検証しません。正規表現がグローバルでない場合、返されたイテレーターは exec()
の結果を一度返し、その後 undefined
を返します。正規表現がグローバルである場合、返されたイテレーターの next()
メソッドが呼び出されるたびに、正規表現の exec()
を呼び出し、結果を返します。
正規表現が粘着的でグローバルな場合、粘着的な照合を行います。つまり lastIndex
以降は照合しません。
console.log(Array.from("ab-c".matchAll(/[abc]/gy)));
// [ [ "a" ], [ "b" ] ]
現在の照合が空文字列の場合、lastIndex
が進みます。正規表現に u
フラグがある場合、Unicode コードポイント 1 つ分進みます。
console.log(Array.from("😄".matchAll(/(?:)/g)));
// [ [ "" ], [ "" ], [ "" ] ]
console.log(Array.from("😄".matchAll(/(?:)/gu)));
// [ [ "" ], [ "" ] ]
このメソッドは RegExp
サブクラスで matchAll()
の動作をカスタマイズするために存在します。
例
直接呼び出し
このメソッドは String.prototype.matchAll()
, とほぼ同様に使用することができますが、 this
の値と引数の順序が違う点が異なります。
const re = /[0-9]+/g;
const str = "2016-01-02";
const result = re[Symbol.matchAll](str);
console.log(Array.from(result, (x) => x[0]));
// [ "2016", "01", "02" ]
サブクラスでの [Symbol.matchAll]()
の使用
RegExp
のサブクラスは [Symbol.matchAll]()
メソッドを上書きして既定の動作を変更することができます。
例えば、 Array
をイテレーターの代わりに返すことができます。
class MyRegExp extends RegExp {
[Symbol.matchAll](str) {
const result = RegExp.prototype[Symbol.matchAll].call(this, str);
return result ? Array.from(result) : null;
}
}
const re = new MyRegExp("([0-9]+)-([0-9]+)-([0-9]+)", "g");
const str = "2016-01-02|2019-03-07";
const result = str.matchAll(re);
console.log(result[0]);
// [ "2016-01-02", "2016", "01", "02" ]
console.log(result[1]);
// [ "2019-03-07", "2019", "03", "07" ]
仕様書
Specification |
---|
ECMAScript Language Specification # sec-regexp-prototype-%symbol.matchall% |
ブラウザーの互換性
BCD tables only load in the browser