訳の正確性を保証するものではありませんので必要に応じて原文であるEcma InternationalのECMA-262にある ECMA-262.pdf ( ECMA-262 5.1 Edition )を参照下さい。
訳:2012年04月 webzoit.net
正規表現のパターンは、以下で説明したプロセスを使って内部プロシージャに変換されます。 実装は、結果が同じ長さになるように以下に挙げた内の1つより効率的なアルゴリズムを使用することが奨励されます。 内部プロシージャは、RegExpオブジェクトの内部プロパティ[[Match]]の値として使用されます。
プロシージャとは、(一連の)手続き(を行う関数、メソッド等)
以下の説明では、次の変数を使用します。
・入力は、正規表現のパターンによってマッチした文字列とする。 ・表記法 input[n] は、n が0(内包的)とInputLength(排他的)の範囲とすることができる場合、入力の n 番めの文字を意味するものとする。 ・InputLengthは、入力文字列内の文字数とする。 ・NcapturingParensは、パターン内で(例えば、 Atom :: ( Disjunction ) プロダクションが拡張される回数の総数のように)キャプチャしたカッコの左かっこの総数であるものとする。 ・キャプチャしたカッコの左かっこは、 Atom :: ( Disjunction ) プロダクションの ( ターミナルによってマッチされる( というパターン文字であるものとする。 ・IgnoreCaseは、RegExpオブジェクトのignoreCaseプロパティを設定することであるものとする。 ・Multilineは、RegExpオブジェクトのmultilineプロパティを設定することであるものとする。
更に、以下の説明は、次の内部データ構造を使用します。
・任意のCharSetは、数学的な文字の集合とする。 ・任意のStateは、endIndexが整数、且つ、capturesがNcapturingParens値の内部配列である場合において指定したペア(endIndex, captures)とする。 Statesは、正規表現のマッチングアルゴリズム内で特定のマッチする状態を表す為に使用されるものとする。 endIndexは、 captures がキャプチャしたカッコの結果を保持する場合、そのパターンによってそれまでマッチしていた最後の入力文字のインデックスに1を加えるものとする。 captures の n 番めの要素は、キャプチャしたカッコの n 番めのセットによって得られた値を表す文字列か、または、キャプチャするカッコの n 番めのセットに、まだ到達していない場合のundefinedの何れかであるものとする。 バックトラッキングの為、多くのStatesが、マッチング処理中に(任意の時点で)使用されている場合もあるものとする。 ・ MatchResultは、State、または、マッチに失敗したことを示す特殊なトークン(字句)である failure の何れかであるものとする。 ・ Continuationプロシージャは、内部クロージャ(例えば、既に値にバインドされている任意の引数を伴う内部プロシージャ)は、1つのState引数を取り、MatchResultの結果を返すものとする。 内部クロージャは、当該クロージャを生成する関数内でバインドされる変数を参照し、当該クロージャは、クロージャが生成された時点でこれらの変数を使用するものとする。 中間の状態で始まる入力文字列に対するパターンの(クロージャの既にバインドされている引数によって指定した)残りの部分をマッチする為のContinuationの試行は、そのState引数によって与えられるものとする。 マッチが成功した場合、そのContinuationは、それが到達した最後のStateを返し、マッチが失敗した場合には、そのContinuationは、failureを返すものとする。 ・Matcherプロシージャは、1つの State と 1つの Continuation の2つを引数に取り、MatchResultの結果を返す内部クロージャであるものとする。 中間の状態で始まる入力文字列に対するパターンの(クロージャの既にバインドされている引数によって指定した)中間のサブパターンとのマッチの為のMatcherの試行は、そのState引数によって与えられるものとする。 Continuation引数は、当該パターンの残りにマッチするクロージャとすべきものとする。 新たなStateを取得する為、パターンのサブパターンとのマッチング後、そのMatcherは、パターンの残りがうまくマッチする場合、テストする為に新たなState上でContinuationを呼ぶものとする。 可能であれば、当該Matcherは、Continuationによって返したStateを返すものとし、不可能であれば、Matcher は、成功か、全ての可能性を使いきるかの何れかになるまで繰り返しContinuationを呼び、その選択ポイントで異なる選択を試す場合もあるものとする。 ・AssertionTesterプロシージャは、State引数を取り、Booleanの結果を返す内部クロージャとする。 アサーションテスターは、入力文字列内の現在の場所に対して(クロージャの既にバインドされている引数によって指定した)仕様上の条件をテストし、条件にマッチする場合、true、そうではない場合、falseを返すものとする。 ・EscapeValueは、1つの文字か、1つの整数であるものとする。 EscapeValueは、エスケープシーケンス DecimalEscape として解釈する表記法の為に使用されるものとする。 整数 n が、キャプチャしたカッコの n 番めのセットへの後方参照として解釈されるエスケープシーケンスを意味する場合、文字 ch が、文字 ch として解釈されるエスケープシーケンスという意味であるものとする。
プロダクション Pattern :: Disjunction は、次のように評価します。
1. Matcher m を取得する為、 Disjunction を評価する 2.文字列 str と 整数 index という2つの引数を取り、次を実行する内部クロージャを返す 1. Input には、文字列 str を与えるものとする この変数は、 15.10.2 にあるアルゴリズムを介して利用されるものとする 2. InputLength は、Input の長さとする この変数は、 15.10.2 にあるアルゴリズムを介して利用されるものとする 3. c は、MatchResultが成功したものとして当該State引数を常に返すContinuationとする 4. cap は、索引付けした1からNcapturingParensまでundefined値であるNcapturingParensの内部配列とする 5. x は、 当該State (index, cap) とする 6. m(x, c) を呼び、その結果を返す
[注釈] パターンは、内部プロシージャの値について("compiles")を評価します。 RegExp.prototype.exec は、その後、文字列と当該パターンが確実に当該文字列内のオフセット位置にある開始点とマッチするかどうかを決める為の文字列内のオフセットを、更にマッチする場合、キャプチャするカッコの値にこのプロシージャを適用します。 パターンをコンパイルするように設計されている 15.10.2 にあるアルゴリズムは、SyntaxError例外を投げ(スローし)、他方で1度パターンがコンパイルに成功すると(メモリ不足(out-of-memory)のようなどこかで発生するホスト定義の例外である場合を除き、)例外を投げることができない文字列内でマッチを見つける為に内部プロシージャをその結果に適用します。
プロダクション Disjunction :: Alternative は、 Matcher と Matcher を返すことで得られる Alternative を評価します。 プロダクション Disjunction :: Alternative | Disjunction は、 次のように評価します。
1. Matcher m1 を得る為に Alternative を評価 2. Matcher m2 を得る為に Disjunction を評価 3. 任意の State x と任意の Continuation c という2つの引数を取り、次を実行する内部 Matcher クロージャを返す 1. m1(x, c) を呼び、r は、その結果とする 2. r が、failureではない場合、r を返す 3. m2(x, c) を呼び、その結果を返す
[注釈] 正規表現演算子 | は、2つの選択肢を分割します。 1つめのパターンは、(正規表現の続きにより続けられる)左側のAlternativeへのマッチングを試行し、失敗した場合、(正規表現の続きにより続けられる)右側のDisjunctionへのマッチングを試行します。 左側のAlternative、右側のDisjunction、その後半の全ては、選択点を持ち、後半にある全ての選択点は、左側のAlternativeにある次の選択肢に移動する前に試行されます。 左側のAlternativeにある選択肢を使いきった場合、左側のAlternativeの代わりに右側のDisjunctionが、試行されます。 \ | によってスキップしたパターンのキャプチャするカッコ内の部分は、文字列の代わりにundefined値を生成します。 このように例えば、
/a|ab/.exec("abc")
は、"a"という結果を返すのであって"ab"を返すわけではありません。 更に
/((a)|(ab))((c)|(bc))/.exec("abc")
は、配列
["abc", "a", "a", undefined, "bc", undefined, "bc"]
を返すのであって
["abc", "ab", undefined, "ab", "c", "c", undefined]
を返すわけではありません。
プロダクション Alternative :: [empty] は、 任意の State x と任意の Continuation c という2つの引数を取り、 c(x) を呼んだ結果を返す Matcher を実行することによって評価します。 プロダクション Alternative :: Alternative Term は、次のように評価します。
1. Matcher m1 を取得する為に Alternative を評価 2. Matcher m2 を取得する為に Term を評価 3. 任意の State x と任意の Continuation c という2つの引数を取り、次を実行する内部 Matcher クロージャを返す 1. 1つのState引数 y を取る Continuation d を生成し、 m2(y, c) を呼んだ結果を返す 2. m1(x, d) を呼び、その結果を返す
[注釈] 連続した Terms は、入力文字列の連続的な部分と同時にマッチするように試行します。 左側の Alternative 、右側の Term 、正規表現の後半の全ては、選択点を持ち、後半の全ての選択肢は、右側の Term 内の次の選択肢に移動する前に試行され、右側の Term 内にある全ての選択点は、左側の Alternative 内にある次の選択点に移動する前に試行されます。
プロダクション Term :: Assertion は、 任意の State x と任意の Continuation c という2つの引数を取り、次を実行する内部 Matcher クロージャを実行することによって評価します。
1. AssertionTester t を取得する為に Assertion を評価 2. t(x) を呼び、 r は、結果となるBoolean値とする 3. r が、 falseである場合、 failure を返す 4. c(x) を呼び、その結果を返す
プロダクション Term :: Atom は、 Matcher とその Matcher を返すことによって得られる Atom を評価することによって評価します。 プロダクション Term :: Atom Quantifier は、次のように評価します。
1. Matcher m を取得する為に Atom を評価 2.整数 min、整数(または、∞) max、Boolean値 greedy という3つの結果を取得する為に Quantifier を評価 3. max が有限、且つ、min より小さい場合、SyntaxError例外を投げる(スローする) 4. parenIndex は、このプロダクションの拡張の Term の左側に現れる正規表現全体の中にあるキャプチャした左カッコの数とする これは、この Term を囲む Atom :: ( Disjunction ) プロダクションの総数を加えた、このプロダクションの Term に優先して Atom :: ( Disjunction ) プロダクションが拡張される回数の総数 5. parenCount は、このプロダクションの Atom の拡張内でキャプチャした左カッコの数とする これは、このプロダクションの Atom によって囲まれた Atom :: ( Disjunction ) プロダクションの総数 6.任意の State x と任意の Continuation c という2つの引数を取り、次を実行する内部 Matcher クロージャを返す 1. RepeatMatcher(m, min, max, greedy, x, c, parenIndex, parenCount) を呼び、その結果を返す
抽象操作 RepeatMatcher は、 Matcher m 、整数 min 、整数(または∞) max、Boolean値 greedy 、 State x 、 Continuation c 、整数 parenIndex 、整数 parenCount という8つのパラメータを取り、次を実行します。
1. max がゼロである場合、 c(x) を呼び、その結果を返す 2. State 引数 y を1つ取り、内部 Continuation クロージャ d を生成し、次を実行する 1. min がゼロ、且つ、y の endIndex が、x の endIndex と等しい場合、 failure を返す 2. min がゼロである場合、 min2 は、ゼロとし、それ以外の場合、 min2 は、min-1 とする 3. max が、∞である場合、 max2 は、∞とし、それ以外の場合、 max2 は、max-1 とする 4. RepeatMatcher(m, min2, max2, greedy, y, c, parenIndex, parenCount) を呼び、その結果を返す 3. cap は、 x のキャプチャ内部配列の最新のコピーとする 4. parenIndex < k 、且つ、 k ≦ parenIndex+parenCount を満たす整数 kごとに cap[k] に undefined を設定する 5. e は、 x の endIndex とする 6. xr は、State (e, cap) とする 7. min が、ゼロである場合、 m(xr, d) を呼び、その結果を返す 8. greedy が、 falseである場合、 a. c(x) を呼び、 z は、その結果とする b. z が、 failureではない場合、z を返す c. m(xr, d) を呼び、その結果を返す 9. m(xr, d) を呼び、z は、その結果とする 10. z が、 failureではない場合、z を返す 11. c(x) を呼び、その結果を返す
[注釈 1] Quantifier (量指定子)が続く Atom は、 Quantifier によって指定した回数の数字が表示されます。 当該 Atom パターンが、後半とマッチしている間、可能な限り、少数回繰り返す場合、 Quantifier は、非greedyとすることができますし、また、当該 Atom パターンが、後半とマッチしている間、可能な限り、多数回繰り返す場合、greedyとすることができます Atom パターンは、マッチする入力文字列以上に繰り返される為、 Atomの異なる反復では、入力部分文字列とマッチさせることが可能です。 [注釈 2] 当該 Atom と正規表現全体の内の後半部分は、選択点を持ち、当該 Atom は、可能な限り多くの回数(非greedyの場合、数回)マッチさせる最初のものです。 後続の全ての選択肢は、 Atom の最後の反復内にある次の選択肢に移動する前に試行されます。 Atom の最後(n 番め)の反復内にある全ての選択肢は、現在利用可能な Atom の反復が多数回、または数回あることが判明する場合のある時点で Atom の(n-1 番め)の反復の次から最後までの st 内の次の選択肢に移動する前に試行されます。 これらは、 Atom の(n-1 番め)の反復 st にある次の選択肢に移動する前に使い果たされ(ますが、再び、可能な限り少数回または、多数回の何れかで開始し)、...等々。
"abc"を返す
/a[a-z]{2,4}?/.exec("abcdefghi")
と"abcde"を返す
/a[a-z]{2,4}/.exec("abcdefghi")
を比較してみましょう この
/(aa|aabaac|ba|b|c)*/.exec("aabaac")
についても考えてみましょう。 これは、上記の順番の選択点によって
["aabaac", "aabaac"] ["aabaac", "c"]
の何れでもなく、 以下の配列を返します。
["aaba", "ba"]
上記選択点の順は、(単項表記で表した)2つの数字の最大公約数となる正規表現を書く為に使用されることが可能です。 次の例は、10と15のgcd(greatest common divisor/最大公約数)を算出します。
"aaaaaaaaaa,aaaaaaaaaaaaaaa".replace(/^(a+)\1*,\1+$/,"$1")
これは、単項表記"aaaaa"内のgcd(greatest common divisor/最大公約数)を返します。 [注釈 3] RepeatMatcher のステップ4は、 Atom が繰り返される度ごとに Atom のキャプチャをクリアします。 以下の正規表現内でその動作を確認する(見る)ことができます。 この正規表現
/(z)((a+)?(b+)?(c))*/.exec("zaacbbbcac")
は、以下ではなく、
["zaacbbbcac", "z", "ac", "a", "bbb", "c"]
以下の配列を返します。
["zaacbbbcac", "z", "ac", "a", undefined, "c"]
なぜなら、最も外側の * の各反復(イタレーション)は、定量化した Atom 内に含む全てのキャプチャ文字列をクリアするからであり、このケースでは、2,3,4,5と番号付けしたキャプチャ文字列を含みます。 [注釈 4] RepeatMatcher の d クロージャのステップ1は、それ以上の反復が考えられないカラの文字列とマッチする Atom の多くの拡張を満たしている最小の反復数1回という状態です。 これは、以下のようなパターンにおいて正規表現エンジンが無限ループに陥ることを防止します。
パターン
/(a*)*/.exec("b")
や若干より複雑な
/(a*)b\1+/.exec("baaaac")
は、
["b", ""]
という配列を返します。
プロダクション Assertion :: ^ は、任意の State 引数 x を取り、次を実行する内部 AssertionTester クロージャを返すことによって評価します。
1. e は、 x の endIndex とする 2. e が、ゼロである場合、 true を返す 3. Multiline が、 falseである場合、 false を返す 4.文字 Input[e-1] が、LineTerminator の1つである場合、 true を返す 5. false を返す
プロダクション Assertion :: $ は、任意の State 引数 x を取り、次を実行する内部 AssertionTester クロージャを返すことによって評価します。
1. e は、 x の endIndex とする 2. e が、InputLength と等しい場合、 true を返す 3. multiline が、 falseである場合、 false を返す 4.文字 Input[e] が、LineTerminator の1つである場合、 true を返す 5. false を返す
プロダクション Assertion :: \ b は、任意の State 引数 x を取り、次を実行する内部 AssertionTester クロージャを返すことによって評価します。
1. e は、 x の endIndex とする 2. IsWordChar(e-1) を呼び、 a は、Booleanの結果を返す 3. IsWordChar(e) を呼び、 b は、Booleanの結果を返す 4. a が、 true 、且つ b が、 falseである場合、 trueを返す 5. a が、 false 、且つ b が、 trueである場合、 trueを返す 6. false を返す
プロダクション Assertion :: \ B は、任意の State 引数 x を取り、次を実行する内部 AssertionTester クロージャを返すことによって評価します。
1. e は、 x の endIndex とする 2. IsWordChar(e-1) を呼び、 a は、Booleanの結果を返す 3. IsWordChar(e) を呼び、 b は、Booleanの結果を返す 4. a が、 true 、且つ b が、 falseである場合、 falseを返す 5. a が、 false 、且つ b が、 trueである場合、 falseを返す 6. true を返す
プロダクション Assertion :: ( ? = Disjunction ) は、次のように評価します。
1. Matcher m を取得する為に Disjunction を評価 2. 任意の State x と任意の Continuation c という2つの引数を取り、次のステップを実行する内部 Matcher クロージャを返す 1. d は、成功したMatchResultのように当該Stateの引数を常に返すContinuationとする 2. m(x, d) を呼び、 r は、その結果とする 3. r が、 failure である場合、 failure を返す 4. y は、 r の State とする 5. cap は、 y の キャプチャ内部配列とする 6. xe は、 x の endIndex とする 7. z は、 State (xe, cap) とする 8. c(z) を呼び、その結果を返す
プロダクション Assertion :: ( ? ! Disjunction ) は、次のように評価します。
1. Matcher m を取得する為に Disjunction を評価 2.任意の State x と任意の Continuation c という2つの引数を取り、次のステップを実行する内部 Matcher クロージャを返す 1. d は、成功したMatchResultのように当該Stateの引数を常に返すContinuationとする 2. m(x, d) を呼び、 r は、その結果とする 3. r が、 failure ではない場合、 failure を返す 4. c(x) を呼び、 その結果を返す
抽象操作 IsWordChar は、整数のパラメータ e を取り、次を実行します。
1. e == -1 または、 e == InputLength である場合、 false を返す 2. c は、文字 Input[e] とする 3. c が、以下の63文字の内の1つである場合、 true を返す a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 _ 4. false を返す
プロダクション Quantifier :: QuantifierPrefix は、次のように評価します。
1.整数 min と整数 (または、 ∞) max という2つの結果を取得する為にQuantifierPrefixを評価 2. min, max, trueという3つの結果を返す
プロダクション Quantifier :: QuantifierPrefix ? は、次のように評価します。
1.整数 min と整数 (または、 ∞) max という2つの結果を取得する為にQuantifierPrefixを評価 2. min, max, falseという3つの結果を返す
プロダクション QuantifierPrefix :: * は、 0 と ∞ という2つの結果を返す事によって評価します。 プロダクション QuantifierPrefix :: + は、 1 と ∞ という2つの結果を返す事によって評価します。 プロダクション QuantifierPrefix :: ? は、 0 と 1 という2つの結果を返す事によって評価します。 プロダクション QuantifierPrefix :: { DecimalDigits } は、次のように評価します。
1. i は、DecimalDigits ( 7.8.3 参照)の MV とする 2. i と i という2つの結果を返す
プロダクション QuantifierPrefix :: { DecimalDigits , } は、次のように評価します。
1. i は、DecimalDigits の MV とする 2. i と ∞ という2つの結果を返す
プロダクション QuantifierPrefix :: { DecimalDigits , DecimalDigits } は、次のように評価します。
1. i は、1つめの DecimalDigits とする 2. j は、2つめの DecimalDigits とする 3. i と j という2つの結果を返す
プロダクション Atom :: PatternCharacter は、次のように評価します。
1. ch は、PatternCharacter によって表した文字とする 2. A は、文字 ch を含んでいる1つの要素(one-element) CharSet とする 3. CharacterSetMatcher(A, false) を呼び、その Matcher の結果を返す
プロダクション Atom :: . は、次のように評価します。
1. A は、LineTerminator を除く全ての文字の集合とする 2. CharacterSetMatcher(A, false) を呼び、その Matcher の結果を返す
プロダクション Atom :: \ AtomEscape は、 Matcher と実行中のその Matcher を取得する為に評価中の AtomEscape を評価します。 プロダクション Atom :: CharacterClass は、次のように評価します。
1. 任意の CharSet A と 任意の Booleanフラグinvert を取得する為にCharacterClassを評価 2. CharacterSetMatcher(A, invert) を呼び、その Matcher の結果を返す
プロダクション Atom :: ( Disjunction ) は、次のように評価します。
1. Matcher m を取得する為にDisjunctionを評価 2. parenIndex は、このプロダクションの拡張の初期の左カッコに現れる正規表現全体にあるキャプチャする左カッコの数とする これは、この Atom を囲む Atom :: ( Disjunction ) プロダクションの総数を加えた、このプロダクションの Atom に優先して Atom :: ( Disjunction ) プロダクションが、拡張される回数の総数 3.任意の State x と任意の Continuation c という2つの引数を取り、次のステップを実行する内部 Matcher クロージャを返す 1. 1つの State引数を取り、次のステップを実行する内部 Continuation クロージャ d を生成する 1. cap は、y のキャプチャ内部配列の最新のコピーとする 2. xe は、 x の endIndex とする 3. ye は、 y の endIndex とする 4. s は、 xe (を含む xe )から ye ( を含まない ye )までの位置にある Input の文字である文字列を持つ最新の文字列とする 5. cap[parenIndex+1] に s を設定する 6. z は、State (ye, cap) とする 7. c(z) を呼び、その結果を返す 2. m(x, d) を呼び、その結果を返す
プロダクション Atom :: ( ? : Disjunction ) は、 Matcher と実行中のその Matcher を取得する為に評価中のDisjunctionを評価します。 抽象操作CharacterSetMatcherは、任意の CharSet A と任意のBooleanフラグinvertという2つの引数を取り、次を実行します。
1.任意の State x と任意の Continuation c という2つの引数を取り、次のステップを実行する内部 Matcher クロージャを返す 1. e は、 x の endIndex とする 2. e == InputLength である場合、 failure を返す 3. ch は、文字 Input[e] とする 4. cc は、 Canonicalize(ch) の結果とする 5. invert が、 falseである場合、 a Canonicalize(a) == cc というような集合 A のメンバが存在しない場合、 failure を返す 6.それ以外の場合、invert は、 true であり、 a Canonicalize(a) == cc というような集合 A のメンバが存在する場合、 failure を返す 7. cap は、x のキャプチャ内部配列とする 8. y は、 State (e+1, cap) とする 9. c(y) を呼び、その結果を返す
抽象操作 Canonicalize は、文字パラメータ ch を取り、次のステップを実行します。
1. IgnoreCase が、 false である場合、 ch を返す 2. u 1文字のString ch上で標準組み込みメソッド String.prototype.toUpperCase を呼んだかのように大文字に変換した ch とする 3. u が、単一の文字で構成されていない場合、 ch を返す 4. cu は、u の文字とする 5. ch のコードユニット値が、10進数の128より大きいか等しく、且つ、cu のコードユニット値が、10進数の128より小さい場合、 ch を返す 6. cu を返す
[注釈 1] 書式 ( Disjunction ) のカッコは、パターン Disjunction のコンポーネントを共にグループ化することとマッチした結果の保存の両方を提供します。 その結果は、置換文字列内で参照した、または、正規表現がマッチした内部プロシージャから得られた配列の一部として返した後方参照(非ゼロの10進数が続く\)内の何れかで使用されることが可能です。 カッコのキャプチャリング動作を抑制するには、代わりに書式 (?: Disjunction ) を使用します。 [注釈 2] 書式 (?= Disjunction ) は、先読みするゼロ幅位置を指定します。 それを成功させる為には、パターンの内側の Disjunction は、現在の位置でマッチしなければいけませんが、現在の位置は、後半とマッチする前に進められることはありません。 Disjunction が、複数の方法で現在位置でマッチする場合、最初の1つだけが試行されます。 他の正規表現の演算子とは異なり、 (?= という書式にバックトラッキングはありません。(この一風変わった動作は、Perlから継承されます。) これは、Disjunctionが、キャプチャするカッコとそれらのキャプチャへの後方参照を含むパターンの後半を含む場合に限ったことです。 例えば、
/(?=(a+))/.exec("baaabac")
は、1つめの b の直後のカラの文字列にマッチし、よって、その配列である
["", "aaa"]
を返し、先読みへのトラックバックの不足を例示する為に考慮すると、これは、
/(?=(a+))a*b\1/.exec("baaabac")
となり、この式は、
["aaaba", "a"]
ではなく、
["aba", "a"]
を返します。 [注釈 3] 書式 (?! Disjunction ) は、ゼロ幅の負の先読みを指定します。 それを成功させる為には、パターンの内側の Disjunction が、現在位置でのマッチに失敗しなければいけません。 現在位置は、後半にマッチする前に進められることはありません。 Disjunctionは、キャプチャするカッコを含むことができますが、それらへの後方参照は、Disjunctionそれ自身の内部からのみ検出します。 パターン内の他の場所からこれらのキャプチャするカッコへの後方参照は、成功するパターンにおいて負の先読みが失敗しなければいけないということになるので常に undefined を返します。 例えば、
/(.*?)a(?!(a+)b\2c)\2(.*)/.exec("baaabaac")
は、 a の中で何らかの正の数字 n が直後に続かない a である a b 、(1つめの \2 によって指定した)他の n a、そして a c を探します。 2つめの \2 は、負の先読みの外側にある為、 undefined に対してマッチすることから常に成功します。 正規表現全体としては、配列
["baaabaac", "ba", undefined, "abaac"]
を返します。 全ての文字にマッチする大文字小文字不問状態(case-insignificant)においては、それらが比較される前に暗黙のうちにすぐに大文字に変換されます。 しかしながら、大文字への文字変換中において(変換中の"s" (\u00DF)が、"SS"といったように)1文字以上に文字が拡張される場合、代わりにその文字がそのまま残ります。 その文字はまた、ASCII文字ではないけれども大文字への変換中にそれを(一時的に)ASCII文字にする場合もそのままの文字が残ります。 これは、ASCII文字とのマッチが意図される場合にのみ /[a-z]/i のような正規表現にマッチする \u0131 と \u017F といったようなUnicode文字を防ぐことができます。 更にこれらの変換が許容される場合、 /[^\W]/i は、 a, b, …, h のそれぞれにはマッチしますが、i や s にはマッチしません。
プロダクション AtomEscape :: DecimalEscape は、次のように評価します。
1. EscapeValue E を取得する為にDecimalEscapeを評価 2. E が文字である場合、 a. ch は、 E の文字とする b. A は、文字 ch を含んでいる1つの要素 CharSet とする c. CharacterSetMatcher(A, false) を呼び、その Matcher (クロージャ)の結果を返す 3. E は、整数にしなければならず、 n は、その整数とする 4. n=0 または、 n>NCapturingParens である場合、SyntaxError例外を投げる(スローする) 5.任意の State x と任意の Continuation c という2つの引数を取り、次を実行する内部 Matcher クロージャを返す 1. cap は、 x のキャプチャ内部配列とする 2. s は、 cap[n] とする 3. s が、undefinedである場合、 c(x) を呼び、その結果を返す 4. e は、 x の endIndex とする 5. len は、 s の長さとする 6. f は、 e+len とする 7. f>InputLength である場合、 failure を返す 8.整数 i が存在する場合、 Canonicalize(Input [e+i]) と同じ文字ではない Canonicalize(s[i]) といったような 0 (を含む 0 )と len (を含まない len )の間である場合、 failure を返す 9. y は、 State (f, cap) とする 10. c(y) を呼び、その結果を返す
プロダクション AtomEscape :: CharacterEscape は、次のように評価します。
1.文字 ch を取得する為にCharacterEscapeを評価 2. A は、文字 ch を含んでいる1つの要素 CharSet とする 3. CharacterSetMatcher(A, false) を呼び、その Matcher (クロージャ)の結果を返す
プロダクション AtomEscape :: CharacterClassEscape は、次のように評価します。
1. CharSet A を取得する為にCharacterClassEscapeを評価 2. CharacterSetMatcher(A, false) を呼び、その Matcher (クロージャ)の結果を返す
[注釈] 非ゼロの10進数字 n が続く書式 \ というエスケープシーケンスは、キャプチャするカッコ( 15.10.2.11 参照)の n 番めのセットという結果とマッチします。 正規表現が、 n 番めのキャプチャするカッコより少ないという場合、それはエラーです。 正規表現は、n 以上キャプチャするカッコを持ちますが、キャプチャするものがない為に n 番めのそれが undefinedである場合、後方参照は、常に成功します。
プロダクション CharacterEscape :: ControlEscape は、 Table 23 による文字を返すことにより評価します。
Table 23 -- ControlEscape 文字値 ------------------------------------------------------------------------------------------- ControlEscape コードユニット 名称 記号 ------------------------------------------------------------------------------------------- t \u0009 水平タブ(horizontal tab) <HT> n \u000A ラインフィード(改行)/line feed (new line) <LF> v \u000B 垂直タブ(vertical tab) <VT> f \u000C フォームフィード(form feed) <FF> r \u000D キャリッジリターン(carriage return) <CR> -------------------------------------------------------------------------------------------
プロダクション CharacterEscape :: c ControlLetter は、次のように評価します。
1. ch は、ControlLetterによって表した文字とする 2. i は、ch のコードユニット値とする 3. j は、i を 32 で割った余りとする 4.コードユニット値が j である文字を返す
プロダクション CharacterEscape :: HexEscapeSequence は、 HexEscapeSequence の CV ( 7.8.4 参照)を評価し、その文字結果を返すことによって評価します。 プロダクション CharacterEscape :: UnicodeEscapeSequence は、UnicodeEscapeSequence の CV ( 7.8.4 参照)を評価し、その文字結果を返すことによって評価します。 プロダクション CharacterEscape :: IdentityEscape は、IdentityEscape によって示した文字を返すことによって評価します。
プロダクション DecimalEscape :: DecimalIntegerLiteral [lookahead ? DecimalDigit] は、次のように評価します。 [?部は、∈の否定形]
1. i は、DecimalIntegerLiteral の MV とする 2. i が、ゼロである場合、<NUL> 文字(Unicode値 0000)を含んでいるEscapeValueを返す 3.整数 i を含んでいるEscapeValueを返す
"DecimalIntegerLiteral の MV" の定義は、 7.8.3. にあります。 [注釈] 最初の桁が0である10進数字 n が続く \ がある場合、そのエスケープシーケンスは、後方参照とすることが考慮されます。 n が、正規表現全体にあるキャプチャする左かっこの総数よりも大きい場合、それはエラーです。 \0 は、 <NUL> 文字を表し、10進数字を後続させることはできません。
プロダクション CharacterClassEscape :: d は、0 から 9 までの文字を含んでいる複数文字の10要素(ten-element)のセットを返すことによって評価します。 プロダクション CharacterClassEscape :: D は、CharacterClassEscape :: d によって返したセット内に含まれない全ての文字のセットを返すことによって評価します。 プロダクション CharacterClassEscape :: s は、WhiteSpace(7.2)やLineTerminator(7.3)の右側にある文字を含んでいる文字のセットを返すことによって評価します。 プロダクション CharacterClassEscape :: S は、CharacterClassEscape :: s によって返したセット内に含まれない全ての文字のセットを返すことによって評価します。 プロダクション CharacterClassEscape :: w は、以下63個の文字をを含んでいる文字のセットを返すことによって評価します。
a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 _
プロダクション CharacterClassEscape :: W は、 CharacterClassEscape :: w によって返したセット内に含まれない全ての文字のセットを返すことによって評価します。
プロダクション CharacterClass :: [ [lookahead ? {^}] ClassRanges ] は、 CharSet を取得する為に ClassRanges を評価し、その CharSet と Booleanフラグ falseを返すことによって評価します。[?部は、∈の否定形] プロダクション CharacterClass :: [ ^ ClassRanges ] は、 CharSet を取得する為に ClassRanges を評価し、その CharSet と Booleanフラグ trueを返すことによって評価します。
プロダクション ClassRanges :: [empty] は、カラの CharSet を返すことによって評価します。 プロダクション ClassRanges :: NonemptyClassRanges は、 CharSet を取得する為に NonemptyClassRanges を評価し、その CharSet を返すことによって評価します。
プロダクション NonemptyClassRanges :: ClassAtom は、 CharSet を取得する為に ClassAtom を評価し、その CharSet を返すことによって評価します。 プロダクション NonemptyClassRanges :: ClassAtom NonemptyClassRangesNoDash は、次のように評価します。
1. CharSet A を取得する為、ClassAtom を評価 2. CharSet B を取得する為、NonemptyClassRangesNoDash を評価 3. CharSets A と B の結合(union)を返す
プロダクション NonemptyClassRanges :: ClassAtom - ClassAtom ClassRanges は、次のように評価します。
1. CharSet A を取得する為、1つめの ClassAtom を評価 2. CharSet B を取得する為、2つめの ClassAtom を評価 3. CharSets C を取得する為、 ClassRanges を評価 4. CharacterRange(A, B) を呼び、D は、その結果となる CharSet とする 5. CharSets D と C の結合を返す
抽象操作 CharacterRange は、2つの CharSet パラメータ A と B を取り、次を実行します。
1. A が、ぴったり1文字を含まない場合や B が、ぴったり1文字を含まない場合、SyntaxError例外を投げる(スローする) 2. a は、 CharSet A 内にある1文字とする 3. b は、 CharSet B 内にある1文字とする 4. i は、文字 a のコードユニット値とする 5. j は、文字 b のコードユニット値とする 6. i > j である場合、SyntaxError例外を投げる(スローする) 7. i から j までを包含する番号付けされた文字全てを含むセットを返す
プロダクション NonemptyClassRangesNoDash :: ClassAtom は、 CharSet を取得する為に ClassAtom を評価し、その CharSet を返すことによって評価します。 プロダクション NonemptyClassRangesNoDash :: ClassAtomNoDash NonemptyClassRangesNoDash は、次のように評価します。
1. CharSet A を取得する為、ClassAtomNoDash を評価 2. CharSet B を取得する為、NonemptyClassRangesNoDash を評価 3. CharSets A と B の結合を返す
プロダクション NonemptyClassRangesNoDash :: ClassAtomNoDash - ClassAtom ClassRanges は、次のように評価します。
1. CharSet A を取得する為、ClassAtomNoDash を評価 2. CharSet B を取得する為、ClassAtom を評価 3. CharSets C を取得する為、 ClassRanges を評価 4. CharacterRange(A, B) を呼び、D は、その結果となる CharSet とする 5. CharSets D と C の結合を返す
[注釈 1] ClassRanges は、単一の ClassAtoms とダッシュによって分割した2つの ClassAtoms の範囲の双方または一方について拡張することが可能です。 後者では、 ClassRanges は、1つめの ClassAtom と2つめの ClassAtom の間にある全ての文字を内包的に含み、 ClassAtom が単一の文字を表さない(例えば、一方が\wである)場合、または、1つめの ClassAtom のコードユニット値が、2つめの ClassAtom のコードユニット値よりも大きい場合、エラーが発生します。 [注釈 2] パターンが無視される場合でさえ、範囲内の末尾が2つのケースは、その範囲内に属する文字を決定中は有効となります。 このように、例えば、パターン /[E-f]/i が、記号 [ , \ , ] , ^ , _ , ` と同様の全ての大文字と小文字のASCII文字にマッチする場合、 パターン /[E-F]/i は、文字 E, F, e, f の何れかにだけマッチします。 [注釈 3] 1文字の - (ハイフン) は、文字通り(リテラルとして)扱われたり、任意の範囲を示すことが可能です。 ClassRanges の最初や最後の文字であり、範囲仕様の開始や末端の限界、または、直後に範囲仕様(の限界)が続く場合、文字通り(リテラルとして)扱われます。
プロダクション ClassAtom :: - は、 - (ハイフン)1文字を含む CharSet を返すことによって評価します。 プロダクション ClassAtom :: ClassAtomNoDash は、 CharSet を取得する為に ClassAtomNoDash を評価し、その CharSet を返すことによって評価します。
\ や ] や - ではないプロダクション ClassAtomNoDash :: SourceCharacter は、 SourceCharacter によって表した文字を含む1つの要素 CharSet を返すことによって評価します。 プロダクション ClassAtomNoDash :: \ ClassEscape は、 CharSet を取得する為に ClassEscape を評価し、その CharSet を返すことによって評価します。
プロダクション ClassEscape :: DecimalEscape は、次のように評価します。
1.任意の EscapeValue E を取得する為に DecimalEscape を評価 2. E が、文字ではない場合、SyntaxError例外を投げる(スローする) 3. ch は、 E の文字とする 4.文字 ch を含む1つの要素 CharSetを返す
プロダクション ClassEscape :: b は、 <BS> (Unicode値 0008) 1文字を含む CharSet を返すことによって評価します。 プロダクション ClassEscape :: CharacterEscape は、任意の文字を取得する為に CharacterEscape を評価し、その文字を含む1つの要素 CharSet を返すことによって評価します。 プロダクション ClassEscape :: CharacterClassEscape は、 CharSet を取得する為に CharacterClassEscape を評価し、その CharSet を返すことによって評価します。 [注釈] 任意の ClassAtom は、 \b, \B と後方参照を除く正規表現内で許容される残りのエスケープシーケンスの一部を使用することが可能です。 任意の CharacterClass 内の \b は、 \B と後方参照がエラーを発生させる場合、バックスペース文字を意味します。 ClassAtom 内で後方参照を使用することは、エラーの要因になります。