1

RegExエンジンが、RegExの複数のルックアラウンドパーツに到達したときに内部でどのように機能するか。

私はすでにこの優れた記事を読みましたが、見回しについては説明していません。誰かが同様の方法で一般的にルックアラウンド(ネガティブ、ポジティブ、ビハインド、フォワード)メカニズムを説明できますか?

(また、次の正規表現がエンジンによってどのように解釈されるかを知りたいです:( RegExsは別個の正規表現文字列であり、可変サイズ、つまりinclude+または*

RegEx (?<!RegEx)(?<=RegEx)(?!RegEx)(?=RegEX) RegEx (?<!RegEx)(?<=RegEx)(?!RegEx)(?=RegEx)  RegEx

、私はそれらと何が一致するか知りたくありませんが、エンジンがそれらとどのように動作するかを知りたいのです。それらは単なる例です。ありがとう

NFA(非決定性有限自動化)図または同様の図は、トピックを説明するのに非常に役立ちます。

正規表現.infoを参照しないでください、私はすでにそれを読んでいます!2つの非常に単純な例を使用しました。一般的なエンジンメカニズムについて知りたいです。

4

1 に答える 1

1

先読みは単純です。エンジンが先読み式に遭遇すると、現在の位置を保存し、通常は一致するかどうかを確認します。そうでない場合は、失敗を返します (エンジンが正規表現の前の部分の他のオプションをチェックできるようにします)。存在する場合は、保存された位置を復元し、残りの正規表現のチェックを続けます。

後読みはより困難です。Python では、固定サイズでなければならないという制限があります。これにより、評価が簡単になります。これに遭遇すると、前の [width] 文字が式に一致するかどうかがチェックされ、残りは先読みのように機能します。この固定サイズの制限を使用しない場合、評価は非常に遅くなります。これは、アルゴリズムが複雑になるという意味ではありません。現在の位置より前のすべての文字列 (その前の 0 文字、その前の 1 文字、その前の 2 文字など) を一致するまで、または文字列の先頭に到達します)。

順序に関しては、正規表現はデフォルトで貪欲です。これは、 のような表現では、 が何にも一致しないこと.*(s?)を意味します。これを望まない場合は、またはの後にa を追加します。(s?).*?*+

今あなたの例に:

  • /.*a(?=.*)/最後までのすべてに一致しますa(貪欲です)。(?=.*)常に一致するため、意味がありません。正規表現は省略しても同じです。
  • /.*a(?!a*)/何にも一致しません: 否定先読みの式は常に一致します (「0 回a」の場合のみ)。これは負であるため、先読みは常に失敗することを意味します。
  • /.*a(?=[^a]*)(?=[x])(?![c]*)/何にも一致しません。エンジンは最初.*aに、最後のa. この後に別の が続くことはないaため、最初の先読みは常に成功します (初回のみ)。後に何もない場合、次の先読みは失敗xします (括弧はそこでは役に立たないことに注意してください。[x]は と同じですx)。.*a失敗した場合、(最初と) 2 番目の先読みが一致するまで、短い文字列を試します。2 番目の先読みが一致する場合、最初の先読みは常に一致するため、役に立たないことに注意してください。ただし、3 番目の先読みはすべてを台無しにします: [c]*(これは と同じですc*) は常に一致します (任意の場所で、「この空の文字列は、文字 c の 0 回のリストです」と言うことができます)。これは、否定先読みが常に失敗することを意味します。

興味深いのは、パターンが貪欲でない場合に何が起こるかということです。たとえば、文字列の最初の (最後ではなく) までを/.*?a/含むすべてのものと一致します。aa

于 2012-11-24T10:21:56.060 に答える