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に多くの時間を節約することができます。