私はこれを見つけましたチュートリアル正規表現については、「greedy」、「reluctant」、「possessive」修飾子が何をするのか直感的に理解していますが、私の理解には重大な欠陥があるようです。
具体的には、次の例のようになります。
Enter your regex: .*foo // Greedy qualifier
Enter input string to search: xfooxxxxxxfoo
I found the text "xfooxxxxxxfoo" starting at index 0 and ending at index 13.
Enter your regex: .*?foo // Reluctant qualifier
Enter input string to search: xfooxxxxxxfoo
I found the text "xfoo" starting at index 0 and ending at index 4.
I found the text "xxxxxxfoo" starting at index 4 and ending at index 13.
Enter your regex: .*+foo // Possessive qualifier
Enter input string to search: xfooxxxxxxfoo
No match found.
説明には、入力文字列全体が消費され、文字が消費され、マッチャーがバックオフし、右端の「foo」が逆流された、などと記載されています。
残念ながら、素晴らしい比喩にもかかわらず、何が誰によって食べられるのかまだ理解できません...正規表現エンジンがどのように機能するかを(簡潔に)説明する別のチュートリアルをご存知ですか?
あるいは、次の段落を少し異なる言い回しで説明していただけると大変ありがたいです。
最初の例では、貪欲な量指定子を使用して
.*
、"anything" を 0 回以上繰り返し、その後に文字"f"
、"o"
、 が続くものを検索します"o"
。量指定子は貪欲であるため、.*
式の部分は最初に入力文字列全体を消費します。この時点では、最後の 3 文字 ("f"
、"o"
、"o"
) がすでに消費されているため (誰によって?)、式全体は成功しません。そのため、マッチャーはゆっくりと (右から左へ?) 1 文字ずつ後退し、 の一番右の出現が"foo"
逆流するまで (これは何を意味するのでしょうか?)、一致が成功して検索が終了します。しかし、2 番目の例は消極的であるため、最初に「何も」を消費することから開始します [誰が?]。 は
"foo"
文字列の先頭に表示されないため、最初の文字 ("x"
) を飲み込まざるを得なくなり [誰が飲み込む?]、0 と 4 で最初の一致がトリガーされます。テスト ハーネスは、入力文字列がなくなるまでこのプロセスを継続します。4 と 13 で別の一致が見つかります。3 番目の例では、量指定子が所有格であるため、一致が見つかりません。この場合、入力文字列全体が
.*+
[how?] によって消費され、式の末尾の "foo" を満たすものが何も残りません。所有格量指定子は、バックオフせずに何かのすべてを取得したい状況で使用します [back off とはどういう意味ですか?]。一致がすぐに見つからない場合、同等の貪欲な量指定子よりもパフォーマンスが優れています。
ベストアンサー1
やってみます。
貪欲な量指定子は、まず可能な限り一致します。したがって、 は.*
文字列全体に一致します。次に、マッチャーはf
後続の一致を試みます。しかし、文字が残っていません。そのため、マッチャーは「バックトラック」し、貪欲な量指定子の一致文字を 1 つ少なくします (文字列の末尾の「o」は一致しません)。それでも正規表現の には一致しないf
ため、もう 1 ステップバックし、貪欲な量指定子の一致文字を 1 つ少なくします (文字列の末尾の「oo」は一致しません)。それでも正規表現の には一致しないf
ため、マッチャーはもう 1 ステップバックします (文字列の末尾の「foo」は一致しません)。これで、マッチャーは最終的にf
正規表現の に一致し、o
と次の もo
一致します。成功です!
消極的または「非貪欲」な量指定子は、まず、できるだけ少ない数だけ一致します。したがって、 は.*
最初は何にも一致せず、文字列全体が一致しないままになります。次に、マッチャーはf
後続の一致を試みますが、文字列の一致しない部分は「x」で始まるため、機能しません。そのため、マッチャーはバックトラックし、非貪欲な量指定子がもう 1 文字一致するようにします (今度は「x」に一致し、「fooxxxxxxfoo」は一致しません)。次に、 の一致を試みf
、これが成功し、 と正規表現のo
次の も一致します。成功です!o
あなたの例では、同じプロセスに従って、文字列の残りの一致しない部分「xxxxxxfoo」でプロセスを最初からやり直します。
所有格量指定子は貪欲な量指定子と似ていますが、バックトラックしません。したがって、文字列全体の一致から開始し.*
、一致しないものは何も残りません。その後、正規表現と一致するものは何も残りませんf
。所有格量指定子はバックトラックしないため、一致はそこで失敗します。