在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中以交互方式进行上述操作。)
答案 0 :(得分:30)
你的尝试非常接近;你需要拉.*
,允许匹配与后来的不匹配之间的任意距离进入否定前瞻:
/abc\(.*xyz\)\@!
我想这是有效的,因为对.*
的所有可能匹配都尝试了不匹配,并且只有当所有分支都已用完时,\@!
被声明为已完成。
答案 1 :(得分:2)
这对我有用/abc\(.*xyz\)\@!
答案 2 :(得分:2)
虽然你的问题是关于前瞻性的,但我在寻找外观时发现了它。因此,我将解决方案发布到了lookbehind,以便其他人可以找到它。
如果您搜索的pattern2
前面没有pattern1
,那就是负面的背后搜索,请搜索:
\(pattern1\)\@<!pattern2
答案 3 :(得分:1)
我总是觉得很奇怪,您需要在vim中转义括号,因此我大多数时候都尝试使用{very magic}模式,并通过\v
激活:
/\vabc(.*xyz)@!
答案 4 :(得分:0)
我想我会把它写成/abc\(\(xyz\)\@!.\)*$
我不确定这是否比其他建议更快(我认为可能因为它只检测每个位置一次),但它在概念上有意义:
“abc后跟任何不是xyz的东西,任何次数直到行尾”
我喜欢它比“abc后跟任何没有跟随xyz的东西”更好,就像所提到的其他模式一样。