2014-01-15 7 views
14

Vimでは、abcと一致する行を検索する方法はありますか?後でxyz行に含まれていませんか?したがって、次の行が一致しますvim regexで否定的な先読みを行う方法はありますか?

The abc is the best 
The first three letters are abc 

をし、次は一致しません:

The abc is the best but xyz is cheaper 
The first three letters are abc and the last are xyz 

を、私は次のような構文について知っている:

/abc\(xyz\)\@! 

だけabcxyzを照合し、回避するにその間に何かがある場合はありません。たとえば、abc-xyzです。多くのポジションが後でxyzが一致していないラインであるので、

/abc.*\(xyz\)\@! 

を使用すると、動作しません。

(私はgrep abc <infile | grep -v xyzような何かをするだろうが、私はVimの中で対話的に上記の操作を行いたいコマンドラインであることに注意する必要があります。)

答えて

21

あなたの試みはかなり近かった私の作品;あなたはプルに必要.*負の先読みにマッチし、アサート以降の不一致間の任意の距離を可能に

/abc\(.*xyz\)\@! 

私は非マッチが試行されているので、この作品を推測.*のすべての可能性のあるマッチに対して、すべてのブランチが使い果たされた場合にのみ、\@!が満たされたと宣言されます。

+1

これは、ABC 'と同等ですが(?!。* XYZ)' Perlのようなエンジンで。 – nhahtdh

+0

これは、先読みシンプルがパターンの現在位置から別の本格的な検索を開始し、その結果を使用して先読みが正か否かに応じて続行するかどうかを判断するためです。 – nhahtdh

+1

も ​​':help perl-patterns'を参照してください。 'pattern1'が先行していない' pattern2'に対しては、それは否定的なルックバックです。 '\(pattern1 \)\ @<!pattern2'を検索してください。 – hochl

0

私は、これは他の提案よりも高速であるかどうかわからないんだけど

/abc\(\(xyz\)\@!.\)*$として、私はこれを書きたいと思います(私はそれが一度だけ、各位置をテストするので、それはかもしれないと思う)が、それはとして概念的な意味があります:

「XYZないものが続くABC、行の終わりまで何度でも」

私はより良い言及した他のパターンのような「ABCがXYZが続いていないものが続く」ことが好きです。

1

あなたの質問は先読みに関するものですが、私は見た目を探している間にそれを見つけました。したがって、私は他の人がそれを見つけるかもしれないように見える化に解決策を投稿します。

あなたはpattern1が先行していないpattern2を検索する場合、それは否定後読み、のための検索です:

\(pattern1\)\@<!pattern2 
関連する問題