RegExp.prototype.sticky
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.
sticky
は RegExp
インスタンスのアクセサープロパティで、この正規表現に y
フラグが使用されているかどうかを返します。
試してみましょう
解説
RegExp.prototype.sticky
の値が true
ならば y
フラグが使われており(粘着的正規表現)、そうでなければ false
になります。y
フラグはこの正規表現が対象の文字列を lastIndex
プロパティで示されたインデックスからのみ照合を試みることを示します(そしてグローバル正規表現とは異なり、それ以降のインデックスからの照合は試みません)。
sticky
の設定アクセサーは undefined
です。このプロパティを直接変更することはできません。
粘着的正規表現とグローバル正規表現の両方の場合は、次のようになります。
lastIndex
で照合を開始します。- 照合が成功したら、
lastIndex
は一致部分の末尾まで進みます。 lastIndex
が現在照合している文字列の範囲を超えたら、lastIndex
は 0 をリセットします。
ただし、exec()
メソッドについては、照合に失敗したときの動作が異なります。
exec()
メソッドが粘着的な正規表現で呼び出された場合、その正規表現がlastIndex
での照合に失敗した場合は、正規表現は直ちにnull
を返しlastIndex
を 0 にリセットします。exec()
メソッドがグローバル正規表現で呼び出された場合、その正規表現がlastIndex
での照合に失敗した場合は、次の文字から照合しようとし、一致するものが見つかるか文字列の末尾に達するまで進みます。
exec()
メソッドでは、粘着的かつグローバルな正規表現は、粘着的かつグローバルでない正規表現と同じ動作をします。test()
は exec()
の単純なラッパーなので、test()
はグローバルフラグを無視して同様に粘着的な照合を行います。しかし、他にもグローバル正規表現の挙動を特殊化するメソッドがたくさんあるため、 一般的にはグローバルフラグは粘着フラグと直交します。
String.prototype.matchAll()
(RegExp.prototype[Symbol.matchAll]()
を呼び出す)ではy
,g
,gy
はすべて異なります。y
の正規表現については、matchAll()
では例外が発生します。[Symbol.matchAll]()
はexec()
の結果を 1 つだけ生成しますが、その正規表現のlastIndex
を更新します。g
またはgy
の正規表現については、exec()
の結果を生成するイテレーターを返します。
String.prototype.match()
(RegExp.prototype[Symbol.match]()
を呼び出す)ではy
,g
,gy
はすべて異なります。y
の正規表現については、exec()
の結果を返し、その正規表現のlastIndex
を更新します。g
またはgy
の正規表現については、すべてのexec()
の結果を配列で返します。
String.prototype.search()
(RegExp.prototype[Symbol.search]()
を呼び出す)ではg
フラグは常に無視されます。y
またはgy
の正規表現については、常に0
(文字列の一致箇所の最も先頭)または-1
(先頭に一致しなかった場合)を返し、存在した場合でもlastIndex
を更新しません。g
の正規表現については、文字列中で最初に一致した箇所のインデックスを返します。一致するものが見つからなかった場合は-1
を返します。
String.prototype.split()
(RegExp.prototype[Symbol.split]()
を呼び出す)ではy
,g
,gy
はすべて同じ動作をします。String.prototype.replace()
(RegExp.prototype[Symbol.replace]()
を呼び出す)では、y
,g
,gy
はすべて異なります。y
の正規表現については、現在のlastIndex
の位置で置換を一度実行し、lastIndex
を更新します。g
およびgy
の正規表現については、exec()
に一致したすべての箇所を置換します。
String.prototype.replaceAll()
(RegExp.prototype[Symbol.replace]()
を呼び出す)ではy
,g
,gy
はすべて異なります。y
の正規表現については、replaceAll()
は例外が発生します。g
およびgy
の正規表現については、exec()
に一致したすべての箇所を置換します。
例
sticky フラグのついた正規表現の使用
const str = "#foo#";
const regex = /foo/y;
regex.lastIndex = 1;
regex.test(str); // true
regex.lastIndex = 5;
regex.test(str); // false (lastIndex は粘着フラグで考慮されます)
regex.lastIndex; // 0 (照合に失敗した後でリセット)
アンカーになる sticky フラグ
Firefox の SpiderMonkey エンジンの一部のバージョンでは ^
指定に関するバグがあり、 ^
アサーションで始まり、 sticky フラグを使うことで一致しない式を許可していました。このバグは Firefox 3.6 以降で発生し(それ以前は sticky が実装されていてもバグはありませんでした)、2015 年に修正されました。このバグのためか、仕様書では特に注意を促しているという事実があります。
パターンとともに
y
フラグが使用された場合、^
は常に入力の始まりにのみ一致するか、(rer.[[Multiline]] がtrue
の場合)行の先頭に一致するかです。
以下は正しい挙動の例です。
const regex = /^foo/y;
regex.lastIndex = 2;
regex.test("..foo"); // false - インデックス 2 は文字列の先頭ではない
const regex2 = /^foo/my;
regex2.lastIndex = 2;
regex2.test("..foo"); // false - インデックス 2 は文字列または行の先頭ではない
regex2.lastIndex = 2;
regex2.test(".\nfoo"); // true - インデックス 2 は行の先頭
仕様書
Specification |
---|
ECMAScript Language Specification # sec-get-regexp.prototype.sticky |
ブラウザーの互換性
BCD tables only load in the browser