Regex 在vim正则表达式中有没有一种方法可以进行负前瞻?

Regex 在vim正则表达式中有没有一种方法可以进行负前瞻?,regex,vim,negative-lookahead,Regex,Vim,Negative Lookahead,在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

在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的操作,这对我来说很有效
/abc\(*xyz\)\@!

您的尝试非常接近;您需要
*
拉入反向前瞻中,允许匹配和断言的后续非匹配之间的任意距离

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

我想这是可行的,因为对所有可能的
*
匹配都尝试了不匹配,并且只有当所有分支都已耗尽时,
\@!
才声明为已完成。

我想我应该将其写成
/abc\(\(xyz\)\.\)*$

我不确定这是否比其他建议更快(我认为可能是因为它只测试每个职位一次),但它在概念上是有意义的,因为:

“abc后跟任何非xyz的内容,在行尾之前的任意次数”


与前面提到的其他模式相比,我更喜欢“abc后面跟任何不跟xyz的东西”。

虽然您的问题是关于“向前看”,但我在搜索“向后看”时找到了它。因此,我将解决方案发布到“向后看”,以便其他人可以找到它

如果搜索的
pattern2
前面没有
pattern1
,即反向查找,请搜索:

\(pattern1\)\@<!pattern2

\(pattern1\)\@我总是觉得奇怪,你需要在vim中转义括号,所以我大部分时间都尝试使用“非常神奇”的模式,用
\v
激活:

/\vabc(.*xyz)@!

这相当于类似Perl的引擎中的abc(?。*xyz)
,这是可行的,因为look-ahead simple从模式的当前位置启动另一个完整的搜索,并使用结果决定是否继续(取决于look-ahead是正的还是负的)。另请参见
:帮助perl模式
。对于前面没有
模式1
模式2
,即反向查找,请搜索
\(模式1\)\@。这可能已经过时了-但在我看来,上述解决方案不适用于
xyzac
这样的字符串。OP指出一行中不应该有
xyz
。对我有效的是强制捕获整行:
^(?。*xyz)。*abc(?。*xyz)
(而不是
vim
格式)。请看,这帮助我在地形图中搜索变更线。
/\(“[^”]*“\)=>\(\1\)\@!
这相当于PCRE中的
(?!pattern1)pattern2
。很高兴知道这一点,我以前在VIM Regex地狱里呆过