この例を考えてみましょう。
<pre class="scooby" name="not-code">
content
</pre>
...other HTML...
<pre class="ruby" name="code">
content
</pre>
この正規表現を使用して[*]:
<pre class="(.+)" name="code">
...最初の部分<pre class="
---最初のタグの照合を開始し、次に(.+)
ドキュメントの残り全体を消費します。ただし、残りの正規表現---は" name="code">
そこで一致できないため、2番目のタグで可能な位置が見つかるまでバックオフします。scooby
結果:グループは、からまでのすべてをキャプチャすることになりruby
ます。
(.+?)
これは、欲張りの代わりに欲張りでないものを使用する場合でも当てはまります(.+)
。欲張りでない数量詞は正規表現が可能な限り最短の一致を返す原因になるとよく言われますが、そうではありません。貪欲な正規表現のように、最初の機会にマッチングを開始します。できるだけ早くマッチングを停止します。このような、欲張りでない数量詞が役に立たない状況は珍しいことではありません。
考えるべきもう1つのことは、一致する可能性がない場合です。たとえば、<pre>
最初の属性を持つタグはあるがclass="~whatever~"
、属性を持つタグはない場合name="code"
です。それぞれで、貪欲な人(.+)
は文書全体をむさぼり食い、それからそれが開始点に達するまで後退してからあきらめます。欲張りでない人(.+?)
は後戻りしませんが、ページ全体をスキャンし、はるかにゆっくりと実行します(" name="code">
各位置で効果的に先読みを行います)。
この正規表現で:
<pre class="([^"]+)" name="code">
...タグが一致するかどうかを判断するために、タグの末尾を超えてスキャンする必要はありません。
一致する可能性がない場合はどうなるかを常に考えてください。これはおそらく、正規表現の作成者が行う最も一般的な監視であり、最もパフォーマンスの問題を引き起こすものです。
[*]説明のために、マッチはDOTALLモード(別名シングルラインモード)で実行されていると想定しています。