web-dev-qa-db-ja.com

Vim Regex:CではなくA AND Bを検索する方法

米国大統領のカーター、ブッシュ、クリントン、オバマの名前を含む行がたくさんあります。それらの名前のうちの1つ、いくつかの2、いくつかの3、いくつかの4つすべてが(任意の順序で)含まれているものもあります。

カーターANDクリントンANDオバマの検索方法を知っている->

:g/.*Carter\&.*Clinton\&.*Obama/p

Carter AND(Clinton OR Bush)->を検索する方法を知っています

:g/.*Carter\&\(.*Clinton\|.*Bush\)/p

(それを行うための最も確かな方法があります)

しかし、たとえば、ブッシュANDクリントンNOTカーターの検索方法(および関連する質問を見た)がわかりません。たとえば、ブッシュANDクリントンNOT(カーターORオバマ)。

49
ThG

NOTを表すには、否定のアサーション \@! を使用します。

たとえば、「NOT Bush」は次のようになります。

^\(.*Bush\)\@!

または \v を使用:

\v^(.*Bush)@!

重要:先頭の^に注意してください。肯定的なアサーションのみを使用する場合はオプションですが(1つの一致は他の一致と同様)、否定的なアサーションを固定する必要があります(そうでない場合、行末で一致することができます)。

「ブッシュANDクリントンAND NOT(カーターORオバマ)」の翻訳:

\v^(.*Bush)&(.*Clinton)&(.*Carter|.*Obama)@!

補遺

\&\@= の関係を説明するには:

One&Two&Three

と交換可能です:

(One)@=(Two)@=Three

唯一の違いは、\&が直接ミラーリングする \| (これはより明白で自然なはずです)、\@=はPerlのミラーリング (?=pattern)

51
Pi Delport

Vimの後にPerlスタイルの正規表現を使用する場合は、_\&_を忘れてください。vimにも先読みがあるため、役に立たないvim固有の機能であるため、_r1\&r2_は\%(r1\)\@=r2。しかし、先読みはネガティブバージョンがあり、Perlスタイルのほとんどの正規表現エンジンでも使用できるため、より優れています。 _(Bush AND Clinton AND NOT (Carter OR Obama))_は、次の方法で表現できます。

_g/^\%(.*\%(Carter\|Obama\)\)\@!\%(.*Bush\)\@=.*Clinton/
_

または、非常に魔法で:

_g/^\v%(.*%(Carter|Obama))@!%(.*Bush)@=.*Clinton/
_

_:h /\@=_を参照してください

内部ロジックについて:先読みはブランチのようなものです:正規表現_(reg1)@=reg2_の場合、_reg2_はNの位置で一致すると仮定し(一致はNの位置で開始)、正規表現エンジンは_reg1_もこれに一致するかどうかをチェックしますポジション。そうでない場合、位置は破棄され、正規表現エンジンは_reg2_の次の可能な一致を試みます。負の先読みについても同じですが、_reg1_ doesが一致する場合、正規表現エンジンは位置を破棄します。


例:

正規表現:_(.b)@!a_。

文字列:aba

  1. 見つかった一致:aは位置0(_aba_)で一致します。先読みに一致しようとする:_._はa(_aba_)に一致し、bb(_aba_)に一致します。
  2. 位置1(_aba_)はaと一致しません。
  3. 一致が見つかりました:位置2でa一致(_aba_)。先読みを一致させようとする:_._はa(_aba_)と一致しますが、bは一致しません:シンボルが残っていないため、先読みは失敗します。結果:位置2で正規表現が一致します。
14
ZyX