米国大統領のカーター、ブッシュ、クリントン、オバマの名前を含む行がたくさんあります。それらの名前のうちの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オバマ)。
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)
。
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
。
a
は位置0(_aba
_)で一致します。先読みに一致しようとする:_.
_はa
(_aba
_)に一致し、b
はb
(_aba
_)に一致します。aba
_)はa
と一致しません。a
一致(_aba
_)。先読みを一致させようとする:_.
_はa
(_aba
_)と一致しますが、b
は一致しません:シンボルが残っていないため、先読みは失敗します。結果:位置2で正規表現が一致します。