導入
量指定子には「できるだけ多くマッチしようとする」性質があります。これを 欲張り(greedy) と呼びます。この性質を知らないと「思ったより広い範囲がマッチしてしまう」という、正規表現で最もよくあるつまずきに遭遇します。
説明
たとえば HTML のタグを <.*> で取り出そうとすると、意図とずれます。
パターン: <.*>
対象: <b>太字</b>
マッチ: [<b>太字</b>] ← 最初の < から最後の > まで、丸ごとマッチしてしまう!
.* は「任意の文字を0個以上」ですが、できるだけ長く マッチしようとするため、途中の > を飛び越えて最後の > まで飲み込みます。
これを「できるだけ短く」に変えるのが、量指定子の後ろに付ける ? です。*? +? ?? {n,m}? を 控えめ(lazy/非貪欲) と呼びます。
パターン: <.*?>
対象: <b>太字</b>
マッチ: [<b>]太字[</b>] ← 最短で止まるので、タグを1つずつ取り出せる
もうひとつの手は、そもそも欲張らせないこと。「> 以外を繰り返す」と書けば、> を飲み込みません。
パターン: <[^>]*>
対象: <b>太字</b>
マッチ: [<b>]太字[</b>] ← 否定文字クラスで確実に1タグずつ
多くの場合、<[^>]*> のように 否定文字クラスで書くほうが速く・確実 です。lazy(*?)は便利ですが、まずは「.* は欲張る」という性質を頭に入れておくことが大切です。
やってみよう
.* は「最長」を狙う ―― この欲張りの性質を覚えましょう。短く止めたいときは .*?、あるいは [^X]*(Xを避ける)を使う、と引き出しを持っておくと安心です。