グループのキャプチャについて
キャプチャグループは、一致するものをキャプチャしようとします。これにはいくつかの重要な結果があります。
- 何にも一致しないグループは、何もキャプチャできません。
- 空の文字列にのみ一致するグループは、空の文字列のみをキャプチャできます。
- 試合の試みで繰り返しキャプチャするグループは、最後のキャプチャのみを保持します
- 通常、ほとんどのフレーバーに当てはまりますが、.NET正規表現は例外です(関連する質問を参照)
これは、2つのキャプチャグループを含む単純なパターンです。
(\d+) (cats|dogs)
\___/ \_________/
1 2
与えられ i have 16 cats, 20 dogs, and 13 turtles
た場合、2つの一致があります(rubular.comで見られるように):
16 cats
一致します:グループ1がキャプチャ16
、グループ2がキャプチャcats
20 dogs
一致します:グループ1がキャプチャ20
、グループ2がキャプチャdogs
ここで、パターンのこのわずかな変更について考えてみましょう。
(\d)+ (cats|dogs)
\__/ \_________/
1 2
これで、グループ1が一致\d
します。つまり1桁です。ほとんどのフレーバーでは、繰り返し一致するグループ(この場合はのおかげで+
)は最後の一致のみを保持します。したがって、ほとんどのフレーバーでは、一致した最後の数字のみがグループ1によってキャプチャされます(rubular.comで見られるように)。
16 cats
一致します:グループ1がキャプチャ6
、グループ2がキャプチャcats
20 dogs
一致します:グループ1がキャプチャ0
、グループ2がキャプチャdogs
参考文献
貪欲vs嫌悪vs否定のキャラクタークラスについて
A
次に、「との間のすべて」を一致させる問題について考えてみましょうZZ
。結局のところ、この仕様はあいまいです。これを行う3つのパターンを考え出し、それらは異なる一致を生成します。どちらが「正しい」かは、元のステートメントでは適切に伝えられていない期待に依存します。
入力として以下を使用します。
eeAiiZooAuuZZeeeZZfff
3つの異なるパターンを使用します。
A(.*)ZZ
1つの一致が得られます: AiiZooAuuZZeeeZZ
( ideone.comで見られるように)
- これは貪欲な変種です。グループ1が一致し、キャプチャされました
iiZooAuuZZeee
A(.*?)ZZ
1つの一致が得られます: AiiZooAuuZZ
( ideone.comで見られるように)
- これは気が進まない変種です。グループ1が一致し、キャプチャされました
iiZooAuu
A([^Z]*)ZZ
1つの一致が得られます: AuuZZ
( ideone.comで見られるように)
- これは否定された文字クラスのバリアントです。グループ1が一致し、キャプチャされました
uu
それらが一致したものを視覚的に表現したものは次のとおりです。
___n
/ \ n = negated character class
eeAiiZooAuuZZeeeZZfff r = reluctant
\_________/r / g = greedy
\____________/g
これらの3つの手法の違いに関するより詳細な取り扱いについては、関連する質問を参照してください。
関連する質問
質問に戻る
それでは、質問に戻って、パターンの何が問題になっているのかを見てみましょう。
<h1>()<br
\/
1
グループ1は空の文字列と一致するため、パターン全体は全体としてのみ一致<hr1><br
し、グループ1は空の文字列のみと一致します。
これをさまざまな方法で「修正」することができます。試してみるべき3つの明らかなものは次のとおりです。
<h1>(.*)<br
; よく深い
<h1>(.*?)<br
; 気が進まない
<h1>([^<]*)<br
; 否定された文字クラス
上記のいずれも常に「機能」しないことがわかります。一部のHTMLで問題が発生します。これは予想されることです。正規表現は、この仕事にとって「間違った」ツールです。パターンをますます複雑にして、「正しい」頻度と「間違った」頻度を減らすことができます。おそらく、誰も理解および/または維持できない恐ろしい混乱に陥り、それでも100%の確率で「正しく」機能しない可能性があります。