web-dev-qa-db-ja.com

正規表現の先読み、先読み、および原子団

私はこれらのことを私の正規表現の中に見つけましたが、私がそれらを何に使用できるかについての手掛かりを得ていません。例があるので、それらがどのように機能するのか理解することができますか。

(?!) - negative lookahead
(?=) - positive lookahead
(?<=) - positive lookbehind
(?<!) - negative lookbehind

(?>) - atomic group
315
Spidfire

foobarbarfooという文字列を考えます。

bar(?=bar)     finds the 1st bar ("bar" which has "bar" after it)
bar(?!bar)     finds the 2nd bar ("bar" which does not have "bar" after it)
(?<=foo)bar    finds the 1st bar ("bar" which has "foo" before it)
(?<!foo)bar    finds the 2nd bar ("bar" which does not have "foo" before it)

それらを組み合わせることもできます。

(?<=foo)bar(?=bar)    finds the 1st bar ("bar" with "foo" before it and "bar" after it)

定義

先を見越して(?=)

式Bが続く式Aを見つけます。

A(?=B)

先を見越してマイナスに(?!)

式Bが続かない式Aを見つけます。

A(?!B)

正の(?<=)の後ろを見てください

式Bが先行する式Aを見つけます。

(?<=B)A

負の(?<!)の後ろを見てください

式Bが先行しない式Aを見つけます。

(?<!B)A

原子団(?>)

アトミックグループはグループから出て、グループ内の最初の一致パターンの後で代替パターンを破棄します(バックトラッキングは無効になります)。

  • footsに適用された(?>foo|foot)sは、その最初の選択肢fooに一致し、その後すぐにsが続かないため失敗し、バックトラックが無効になると停止します

非アトミックグループはバックトラックを許可します。後続の前方一致が失敗した場合、式全体の一致が見つかるまで、またはすべての可能性がなくなるまで、後戻りして代替パターンを使用します。

  • foots(foo|foot)sを適用すると、次のようになります。

    1. 最初の選択肢fooと一致させ、sのすぐ後にfootsが続かないため失敗し、2番目の選択肢に戻ります。
    2. 2番目の選択肢footに一致させ、sのすぐ後に続くfootsに成功して停止します。

いくつかのリソース

668
skyfoot

回避策はゼロ幅アサーションです。それらは(前方または後方に基づいて)現在位置の左右に向かって正規表現をチェックし、(正であるか負であるかに基づいて)一致が見つかると成功または失敗し、一致した部分を破棄します。それらは文字を消費しません - それらに続く正規表現のマッチング(もしあれば)は、同じカーソル位置から始まります。

詳しくは regular-expression.info を読んでください。

  • ポジティブルックアヘッド:

構文:

(?=REGEX_1)REGEX_2

REGEX_1が一致する場合にのみ一致します。 REGEX_1との一致後、一致は破棄され、REGEX_2の検索は同じ位置から開始されます。

例:

(?=[a-z0-9]{4}$)[a-z]{1,2}[0-9]{2,3}

REGEX_1は[a-z0-9]{4}$で、4文字の英数字とそれに続く行末に一致します。
REGEX_2は[a-z]{1,2}[0-9]{2,3}で、1文字または2文字の後に2桁または3桁の数字が続きます。

REGEX_1は文字列の長さが確かに4であることを確認しますが、REGEX_2の検索が同じ場所から始まるように文字を消費しません。 REGEX_2は、文字列が他の規則に一致することを確認します。先読みなしでは、長さ3または5の文字列と一致します。

  • 負の先読み

構文:

(?!REGEX_1)REGEX_2

REGEX_1が一致しない場合にのみ一致します。 REGEX_1の確認後、REGEX_2の検索は同じ位置から開始されます。

例:

(?!.*\bFWORD\b)\w{10,30}$

先読み部分は、文字列内のFWORDをチェックし、見つかった場合は失敗します。 FWORDが見つからない場合、先読みは成功し、次の部分では文字列の長さが10から30の間であり、Word文字のみが含まれていることを確認しますa-zA-Z0-9_

先読みは先読みに似ています。現在のカーソル位置の後ろを見ているだけです。 javascriptのようないくつかの正規表現フレーバーは、先読みアサーションをサポートしていません。そしてそれをサポートするほとんどのフレーバー(PHP、Pythonなど)はその先読み部分が固定長であることを要求します。

  • アトミックグループは、基本的に、トークンが一致すると、グループ内の後続のトークンを破棄または忘れます。 原子団 の例については、このページをチェックしてください。
204
Amarghosh

Grokkingの見直し.
先読みと先読みを区別する方法私と一緒に2分のツアーをします。

(?=) - positive lookahead
(?<=) - positive lookbehind

と思います

    A  B  C #in a line

今、私たちはBに尋ねます、あなたはどこにいますか?
Bには、場所を宣言する2つの解決策があります。

1つは、BがAを先に持ち、Cがbebindを持つこと
2、BはCの前(先読み)でAの後ろ(先読み).

見ての通り、2つの解決策では後ろと後ろが逆になっています。
正規表現は解決策2です。

1
DummyHead