貪欲で怠惰な正規表現(理解力の質問)

貪欲で怠惰な正規表現(理解力の質問)

私は正規表現を自分で教えていますが、「貪欲な」対「怠惰な」葉に閉じ込められています。

これまで私が見つけたのは

  • 「Greedy」は、正規表現ができるだけ多くの一致を探すことを意味します。
  • »lazy«は、正規表現ができるだけ少ない数の一致を見つけることを意味します。

私が見つけたほとんどの記事は、a)私が使い続けているプログラミング言語で使用するか、b)アクティベーションの使用を扱っていますが、grepPerlegrepについてgrep -PPerl Mode知識がないので、それは私にとってあまり役に立ちません。

私の理解の問題:私はこの大きなハンマー方式を使うようになりました。

  • 怠惰な反復は、可能な限り短い一致を探します。
  • 結果が長すぎる場合→リピーターの音量を下げてください?
  • 結果がまだ長すぎる場合は→他の解決策を見つけてください。

これは、HTMLコードの例と実験によって得られた結果ですが、圧倒的ではない結果を得ました。

私の要約にいくつかの重要なことがないかどうか、どこにいるのか教えてくれてありがとう。

答え1

最も短いゲームではなく、単に短いゲームです。貪欲モードは可能な最後の一致を見つけようとし、怠惰なモードは最初の可能な一致を見つけようとします。しかし、可能な最初の一致は必ずしも最短ではありません。

入力文字列foobarbazと正規表現o.*a(欲求)またはo.*?a(怠惰)を取得します。

この入力文字列の可能な最短一致はですoba

しかし、正規表現は左から右に一致する項目を探すので、o最初の項目を探します。残りのパターンが一致する場合、そのパターンはそのまま残ります。ofoobarbaz

最初のo.*greedy)はobarbaz(文字列全体)を食べてから、残りのパターン(a)と一致するように逆追跡します。だから最後のaを探してbaz最終的に一致しますoobarba

最初の項目の後、o文字.*?列全体を(ゆっくりと)食べるのではなく、残りのパターンが最初に表示される項目を探します。したがって、最初にo一致しない2番目のものを見てから、一致しないものを見てから、一致するものを見て怠惰なので、停止aします。 (と判明したがそうではない)baaaoobaoba

だから、最も短いバージョンではありませんが、貪欲なバージョンよりも短いです。

答え2

「Perlモード」とは、次のことを意味します。Perl互換正規表現(PCRE). 素人の観点からこれは、Perl、Python、Ruby、PHP、JavaScript、Javaなどの基本正規表現が組み込まれている場合、ほとんどの現代言語でデフォルトで使用される正規表現スタイルです。技術的には微妙な違いがあるかもしれません。ポリメラーゼ連鎖反応Perl正規表現エンジンなどから派生していますが、同じではありませんが、ある言語で正規表現を使用できる場合は、他の言語でも99%同じです。 grepなどの古いツールのデフォルトモードであったPOSIX正規表現として知られている以前のスタイルよりも改善されたため、オプションである位置を支配します。

無欲、別名。怠惰grepを使用して行を一致させるコンテキストでは、修飾子は重要ではありません。持てないからだ。完全な生産ライン怠惰な表現と一致しますが、貪欲な表現と一致しません。その逆も同様です。ただし、スイッチを使用すると、行全体の代わり-oに一致するセグメントの内容が表示されるという違いを確認できます(注:実際のものとは若干異なります--color)。

»echo "123 abc 456 def 789" > eg.txt
»grep -o -P "(\d+\s[A-Za-z]+\s)+" eg.txt
123 abc 456 def 
»grep -o -P "(\d+\s[A-Za-z]+\s)+?" eg.txt
123 abc 
456 def 
»grep -o -P "\d+\s[A-Za-z]+\s\d+" eg.txt
123 abc 456
»grep -o -P "\d+\s[A-Za-z]+\s\d+?" eg.txt
123 abc 4
56 def 7

このようにgrep(使用)すると、貪欲が影響を与えます-o。パターンを含む行全体を一致させるためにgrepを使用している場合、?貪欲ではないことはどちらも重要ではありません。

簡単に言えば、貪欲なマッチングはできるだけ一致し、貪欲ではないマッチングはできるだけ少なく一致します。

関連情報