有没有办法在vim正则表达式中做负面的预测?

Gre*_*ill 28 regex vim negative-lookahead

在Vim中,有没有办法搜索匹配的行abc但是xyz后面还不包含该行?所以以下几行将匹配:

The abc is the best
The first three letters are abc
Run Code Online (Sandbox Code Playgroud)

并且以下内容不匹配:

The abc is the best but xyz is cheaper
The first three letters are abc and the last are xyz
Run Code Online (Sandbox Code Playgroud)

我知道如下语法:

/abc\(xyz\)\@!
Run Code Online (Sandbox Code Playgroud)

但这只是避免匹配,abcxyz而不是中间是否有任何东西,例如abc-xyz.运用

/abc.*\(xyz\)\@!
Run Code Online (Sandbox Code Playgroud)

也不起作用,因为后面的线路中有许多位置xyz不匹配.

(我应该注意,在命令行上我会做类似的事情,grep abc <infile | grep -v xyz但我想在Vim中以交互方式进行上述操作.)

Ing*_*kat 32

你的尝试非常接近; 你需要拉动.*它允许匹配和后面的不匹配之间的任意距离进入负前瞻:

/abc\(.*xyz\)\@!
Run Code Online (Sandbox Code Playgroud)

我猜这是有效的,因为尝试了所有可能匹配的非匹配.*,并且只有当所有分支都已用尽时才\@!声明为已满足.

  • 这相当于 Perl 类引擎中的 `abc(?!.*xyz)`。 (2认同)
  • 另请参阅“:help perl-patterns”。对于前面没有“pattern1”的“pattern2”,即负向后查找,搜索“\(pattern1\)\@&lt;!pattern2”。 (2认同)

hoc*_*chl 5

尽管您的问题与前瞻有关,但我在寻找后向搜索时发现了它。因此,我将解决方案发布到后面,以便其他人可以找到它。

如果您搜索的内容pattern2不以pattern1开头,则后面为负数,请搜索:

\(pattern1\)\@<!pattern2
Run Code Online (Sandbox Code Playgroud)

  • 这相当于 PCRE 中的“(?!pattern1)pattern2”。 (2认同)

han*_*ast 5

我总是觉得很奇怪,您需要在vim中转义括号,因此我大多数时候尝试使用“非常魔术”模式,并通过\v以下方式激活:

/\vabc(.*xyz)@!
Run Code Online (Sandbox Code Playgroud)

  • 很高兴知道这一点,我以前经历过 VIM-Regex 地狱 (2认同)