Regular Expressions
グリーディとレイジーの数量詞
サーチ…
パラメーター
| 数量化 | 説明 |
|---|---|
? | 直前の文字または部分式を0回または1回(好ましくは1)一致させます。 |
* | 直前の文字または部分式を0回以上(可能な限り)一致させます。 |
+ | 前の文字または部分式を1回以上(可能な限り)マッチさせる。 |
{n} | 前の文字または部分式を正確にn回マッチさせる。 |
{min,} | 直前の文字または部分式を分以上一致させます(できるだけ多く)。 |
{0,max} | 直前の文字または部分式を最大またはそれ以下(可能な限りmaxに近い)に一致させます。 |
{min,max} | 直前の文字または部分式を少なくともmin回からmax回まで(可能な限りmaxに近い)マッチさせます。 |
| レイジー数量子 | 説明 |
?? | 直前の文字または部分式を0回または1回(好ましくは0回)一致させます。 |
*? | 直前の文字または部分式を0回以上(可能な限り)一致させます。 |
+? | 直前の文字または部分式を1回以上(可能な限り)一致させます。 |
{n}? | 前の文字または部分式を正確にn回マッチさせる。欲張りと怠け者の違いはありません。 |
{min,}? | 直前の文字または部分式をmin分またはそれ以上(可能な限りminに近い)一致させます。 |
{0,max}? | 直前の文字または部分式を最大またはそれ以下(可能な限り)に一致させます。 |
{min,max}? | 直前の文字または部分式を少なくともmin回からmax回まで一致させます(可能な限りminに近い)。 |
備考
貪欲
グリーディ量子は、バックトラックによって短い一致を探索する前に、できるだけサブパターンを何度も繰り返すよう試みます。
一般的に、貪欲なパターンは可能な限り長い文字列と一致します。
デフォルトでは、すべての量指定子は貪欲です。
怠惰
怠惰な ( 貪欲でない、または嫌な )量子は、拡張によって長い一致を探索する前に、可能な限り数回、サブパターンを繰り返し試みます。
一般に、遅延パターンは可能な最短の文字列と一致します。
定量化を怠惰にするには、単に追加します?既存の定量器、例えば+? 、 {0,5}? 。
貪欲と怠惰の概念はバックトラックエンジンにのみ存在する
欲張り/怠惰な量指定子の概念は、バックトラック正規表現エンジンにのみ存在します。逆戻りしないregexエンジンやPOSIX準拠のregexエンジンでは、量指定子は反復の上限と下限のみを指定し、一致の検出方法は指定しません。これらのエンジンは常に左端の最長文字列に一致します。
貪欲対怠惰
与えられた入力:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
1つの貪欲: A.*Zと1つの怠け者: A.*?Z 2つのパターンを使用しA.*?Z 。これらのパターンは、次の一致をもたらします。
-
A.*Zは1つの一致を生成します:AlazyZgreeedyAlaaazyZ(例: Regex101 、 Rubular ) -
A.*?Zは、AlazyZとAlaaazyZ(例: Regex101 、 Rubular )の2つのマッチを生成しA.*?Z
最初にA.*Zが何をするかに焦点を当てます。それが最初のAと一致Aと、 .*は貪欲で、多くのものと一致しようとし.できるだけ。
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\________________________/
A.* matched, Z can't match
Zは一致しないため、エンジンはバックトラックし、 .*は1つ少ない数に一致する必要があり. :
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\_______________________/
A.* matched, Z can't match
これは、これが最終的に来るまで、さらに数回発生します:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\__________________/
A.* matched, Z can now match
Zはマッチすることができるので、全体のパターンは一致します:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\___________________/
A.*Z matched
対照的に、 A.*?Zの嫌な(怠惰な)反復は、最初に一致するものはほとんどありません.可能な限り、そしてより多くを取る.必要に応じて。これは、入力で2つの一致が見つかった理由を説明しています。
2つのパターンが一致したことを視覚的に表しています。
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\____/l \______/l l = lazy
\_________g_________/ g = greedy
ポリジェネチック・リキッドによる回答に基づく例
POSIX規格には?多くのPOSIX正規表現エンジンには遅延マッチングがありません 。リファクタリング、特に"最高のトリック"を使用すると、場合によってはマッチングに役立つかもしれませんが、真の遅延マッチングを行う唯一の方法は、それをサポートするエンジンを使用することです。
複数のマッチを持つ境界
よく定義された境界線を持つ入力があり、文字列内で複数の一致が予想される場合は、次の2つのオプションがあります。
- 遅延量子の使用
- ネゲートされた文字クラスを使用しています。
次の点を考慮してください。
単純なテンプレートエンジンがあり、 $[foo]ような部分文字列を置き換えたい場合は、 fooは任意の文字列にすることができます。この部分文字列を、 []間の部分に基づいて置き換えたいとします。
\$\[(.*)\]ようなものを試してから、最初のキャプチャグループを使用することができます。
これは、 something $[foo] lalala $[bar] something elseような文字列があれば、 something $[foo] lalala $[bar] something elseに一致するsomething $[foo] lalala $[bar] something elseます
something $[foo] lalala $[bar] something else
| \______CG1______/|
\_______Match______/
捕獲グループはfoo] lalala $[bar有効であるかどうかわからないfoo] lalala $[barです。
あなたは2つのソリューションを持っている
怠惰を使う:この場合、
*lazyを作ることは、正しいものを見つけることの一つの方法です。つまり、式を\$\[(.*?)\]ネゲートされた文字クラスを使用する:
[^\]]式を\$\[([^\]]*)\]ます。
どちらのソリューションでも、結果は同じになります。
something $[foo] lalala $[bar] something else
| \_/| | \_/|
\____/ \____/
キャプチャグループはそれぞれfooとbarです。
ネゲートされた文字クラスを使用すると、バックトラッキングの問題が軽減され、大きな入力になるとCPUに多くの時間を節約することができます。