正規表現エンジンの実装の背後にある実用的な問題に関する信頼できる参照は、Russ Coxによる一連の3つのブログ投稿です。後方参照は、あなたの言語が非正規にするために、そこに記載されているように、彼らが使用して実装されているバックトラックを。
先読みと後読みは、正規表現パターンマッチングエンジンの多くの機能のように、文字列が言語のメンバーであるかどうかを決定するというパラダイムにはまったく適合しません。正規表現ではなく、通常、より大きな文字列内の部分文字列を検索しています。「一致」は言語のメンバーである部分文字列であり、戻り値は大きい文字列内の部分文字列の開始点と終了点です。
先読みと後読みのポイントは、非正規言語に一致する機能を導入することではなく、一致したサブストリングの開始点と終了点をエンジンが報告する場所を調整することです。
http://www.regular-expressions.info/lookaround.htmlの説明に依存しています。この機能をサポートする正規表現エンジン(Perl、TCL、Python、Rubyなど)はすべて、バックトラッキングに基づいているようです(つまり、通常の言語よりもはるかに大きな言語セットをサポートしています)。彼らは、タスクを実行するために実際の有限オートマトンを構築しようとするのではなく、バックトラッキングの比較的「単純な」拡張としてこの機能を実装しているようです。
ポジティブ・ルックアヘッド
正の先読みの構文は(?=
regex)
です。だから、例えばq(?=u)
一致しq
、それが続いている場合にのみu
、とは一致しませんu
。彼らはこれをバックトラックのバリエーションで実装していると思います。正の先読みの前に式のFSMを作成します。それが一致したら、終了位置を覚えて、ポジティブルックアヘッド内の表現を表す新しいFSMを開始します。それが一致する場合、「一致」がありますが、肯定的な先読み一致が開始された位置の直前で一致が「終了」します。
バックトラックなしでは難しいのは、入力の先読みを開始するポイントを覚えて、一致が完了した後に入力テープをこの位置に戻す必要があるということだけです。
負の先読み
負の先読みの構文は(?!
regex)
です。したがって、たとえば、後に続かない場合にのみq(?!u)
一致q
しu
ます。これは、q
後に他の文字が続くかq
、文字列の最後にある可能性があります。先読み式のNFAを作成し、NFAが後続の文字列と一致しない場合にのみ成功することにより、これが実装されると思います。
バックトラックに頼らずにそれを行いたい場合は、先読み表現のNFAを無効にし、肯定的な先読みを処理するのと同じ方法で処理します。
ポジティブルックビハインド
(?<=
)
(?=q)u
u
q
q
nnn
「正規表現で終わる文字列」と、後読み演算子の前にある正規表現の任意の部分との交差を取ることにより、バックトラッキングなしでこれを実装できる場合があります。ただし、後読み正規表現は、入力の現在の始まりよりもさらに後ろを見る必要があるため、これは注意が必要です。
負の後読み
負の後読みの構文は(?<!
regex)
です。したがって、たとえば、に(?<!q)u
一致しますがu
、先頭にが付いていない場合のみですq
。合っているでしょうそれはそうu
ではumbrella
とu
でdoubt
はなく、u
中にquick
。繰り返しますが、これは長さ計算によって行われるように見える正規表現を、との一致を調べる、その多くの文字をバックアップする正規表現が、今後読みが一致する場合にはマッチ全体を失敗します。
正規表現の否定を取得し、後読みのために行うのと同じことを行うことで、バックトラッキングなしでこれを実装できる場合があります。