RegExp.prototype[Symbol.match]()
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2016年9月.
[Symbol.match]() は RegExp インスタンスのメソッドで、 String.prototype.match() がどのように動作するのかを指定します。さらに、これが存在するかどうかが、そのオブジェクトが正規表現とみなされるかどうかにも影響します。
試してみましょう
class RegExp1 extends RegExp {
[Symbol.match](str) {
const result = RegExp.prototype[Symbol.match].call(this, str);
if (result) {
return "VALID";
}
return "INVALID";
}
}
console.log("2012-07-02".match(new RegExp1("([0-9]+)-([0-9]+)-([0-9]+)")));
// Expected output: "VALID"
構文
regexp[Symbol.match](str)
引数
返値
配列 (Array) で、内容はグローバル (g) フラグがあるかどうかで変わります。一致するものが見つからなければ null になります。
gフラグが使用された場合は、この正規表現全体に一致したすべての結果となりますが、キャプチャグループは含まれません。gフラグが使用されなかった場合は、最初に一致したもの全体と、関連するキャプチャグループが返されます。この場合、match()はRegExp.prototype.exec()(一部の追加のプロパティを配列で含む)の結果と同じになります。
解説
このメソッドは、String.prototype.match() で内部的に呼び出されます。
たとえば、次の 2 つの例は同じ結果を返します。
"abc".match(/a/);
/a/[Symbol.match]("abc");
正規表現がグローバル(g フラグ付き)である場合、この正規表現の exec() メソッドは、 exec() が null を返すまで繰り返し呼び出されます。そうでない場合、 exec() は一度だけ呼び出され、その結果が [Symbol.match]() の返値となります。
[Symbol.match]() は exec() を null が返るまで呼び出し続け、最後の照合に失敗すると自動的に正規表現の lastIndex を 0 にリセットします。しかし、正規表現が粘着的であるもののグローバルではない場合、 lastIndex はリセットされません。この場合、 match() を呼び出すたびに異なる結果を返すかもしれません。
const re = /[abc]/y;
for (let i = 0; i < 5; i++) {
console.log("abc".match(re), re.lastIndex);
}
// [ 'a' ] 1
// [ 'b' ] 2
// [ 'c' ] 3
// null 0
// [ 'a' ] 1
正規表現が粘着的かつグローバルな場合、粘着的な照合、つまり lastIndex 以降の照合は行われません。
console.log("ab-c".match(/[abc]/gy)); // [ 'a', 'b' ]
もし現在の照合が空文字列であったとしても、 lastIndex は進みます。正規表現が Unicode 対応モードであれば、Unicode のコードポイント 1 つ分進みます。そうでなければ、 UTF-16 コード単位分進みます。
console.log("😄".match(/(?:)/g)); // [ '', '', '' ]
console.log("😄".match(/(?:)/gu)); // [ '', '' ]
このメソッドは RegExp サブクラス内で照合の動作をカスタマイズするために存在します。
さらに、[Symbol.match]() プロパティはオブジェクトが正規表現であるかどうかをチェックするために使われます。
例
>直接呼び出し
このメソッドは、ほとんど String.prototype.match() と同じ方法で使用することができますが、 this と引数の並び順が異なります。
const re = /[0-9]+/g;
const str = "2016-01-02";
const result = re[Symbol.match](str);
console.log(result); // ["2016", "01", "02"]
サブクラスで @@match を使用
RegExp のサブクラスは、既定の動作を修正するために [Symbol.match]() メソッドをオーバーライドできます。
class MyRegExp extends RegExp {
[Symbol.match](str) {
const result = RegExp.prototype[Symbol.match].call(this, str);
if (!result) return null;
return {
group(n) {
return result[n];
},
};
}
}
const re = new MyRegExp("([0-9]+)-([0-9]+)-([0-9]+)");
const str = "2016-01-02";
const result = str.match(re); // String.prototype.match は re[Symbol.match]() を呼び出す
console.log(result.group(1)); // 2016
console.log(result.group(2)); // 01
console.log(result.group(3)); // 02
仕様書
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-regexp.prototype-%symbol.match%> |
ブラウザーの互換性
Loading…