RegExp.prototype[@@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.

[@@match]()RegExp インスタンスのメソッドで、 String.prototype.matchAll がどのように動作するのかを指定します。

試してみましょう

構文

js
regexp[Symbol.matchAll](str)

引数

str

文字列 (String) で、照合の対象となるものです。

返値

一致したものを表す反復可能なイテレーターオブジェクト(再起動不可)です。それぞれの一致部分は RegExp.prototype.exec() の返値と同じ形の配列です。

解説

このメソッドは内部的に String.prototype.matchAll() を呼び出します。例えば、以下の 2 つの例は同じ結果を返します。

js
"abc".matchAll(/a/g);

/a/g[Symbol.matchAll]("abc");

@@split と同様、 @@matchAll@@species を使用して新しい正規表現を作成するところから始め、何があっても元の正規表現を変更することを避けます。 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" ]

入力がグローバル正規表現であるかどうかの検証は String.prototype.matchAll() で行われます。@@matchAll は入力を検証しません。正規表現がグローバルでない場合、返されたイテレーターは exec() の結果を一度返し、その後 undefined を返します。正規表現がグローバルである場合、返されたイテレーターの next() メソッドが呼び出されるたびに、正規表現の exec() を呼び出し、結果を返します。

正規表現が粘着的でグローバルな場合、粘着的な照合を行います。つまり lastIndex 以降は照合しません。

js
console.log(Array.from("ab-c".matchAll(/[abc]/gy)));
// [ [ "a" ], [ "b" ] ]

現在の照合が空文字列の場合、lastIndex が進みます。正規表現に u フラグがある場合、Unicode コードポイント 1 つ分進みます。

js
console.log(Array.from("😄".matchAll(/(?:)/g)));
// [ [ "" ], [ "" ], [ "" ] ]

console.log(Array.from("😄".matchAll(/(?:)/gu)));
// [ [ "" ], [ "" ] ]

このメソッドは RegExp サブクラスで matchAll() の動作をカスタマイズするために存在します。

直接呼び出し

このメソッドは String.prototype.matchAll(), とほぼ同様に使用することができますが、 this の値と引数の順序が違う点が異なります。

js
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" ]

サブクラスでの @@matchAll の使用

RegExp のサブクラスは [@@matchAll]() メソッドを上書きして既定の動作を変更することができます。

例えば、 Arrayイテレーターの代わりに返すことができます。

js
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

関連情報