Vimで、abc
と一致するが、行の後半にxyz
が含まれていない行を検索する方法はありますか?したがって、次の行が一致します。
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
などの間に何かがある場合は回避しません。使用する
/abc.*\(xyz\)\@!
また、行の後半にxyz
が一致しない位置が多数あるため、機能しません。
(コマンドラインでgrep abc <infile | grep -v xyz
のようなことをしますが、Vimで上記をインタラクティブに実行したいことに注意してください。)
あなたの試みはかなり近かった。 .*
をプルして、一致と後でアサートされた不一致の間の任意の距離を許可する必要があります負の先読みに:
/abc\(.*xyz\)\@!
.*
のすべての可能な一致に対して不一致が試行され、すべてのブランチが使い果たされた場合にのみ\@!
が満たされていると宣言されるため、これは機能すると思います。
あなたの質問は先読みについてですが、私は後読みを探しているときにそれを見つけました。したがって、他の人がそれを見つけることができるように、私は後ろ向きに解決策を投稿します。
pattern2
が前に付いていないpattern1
を検索する場合、つまりネガティブルックビハインドの場合は、次を検索します。
\(pattern1\)\@<!pattern2
私はいつも奇妙だと思っています。vimで角かっこをエスケープする必要があるので、ほとんどの場合、\v
でアクティブ化される「非常に魔法の」モードを使用しようとします。
/\vabc(.*xyz)@!
これは私のために働きます/abc\(.*xyz\)\@!
これを/abc\(\(xyz\)\@!.\)*$
と書くと思います
これが他の提案よりも速いかどうかはわかりませんが(各位置を1回だけテストするためかもしれません)、概念的には次のように意味があります。
「abcの後にxyz以外のものが続く、行末まで何度でも」
上記の他のパターンのように、「abcの後にxyzが続かないものが続く」よりもそれが好きです。