vim 的正向和负向预查

在 Vim 的正则表达式中,预查(Lookaround) 是一种“断言”,用于匹配某个位置前后是否满足特定条件,但不消耗字符(即匹配结果中不包含预查括号内的内容)。

Vim 支持四种预查,分为正向/负向向前/向后两个维度。以下是关键关键字和语法:

1. 核心语法关键字

类型 中文名称 英文术语 Vim 语法 含义
正向预查 正向肯定预查 Positive Lookahead \@= 匹配当前位置之后必须出现的内容
负向预查 正向否定预查 Negative Lookahead \@! 匹配当前位置之后****不能出现的内容
反向预查 反向肯定预查 Positive Lookbehind \@<= 匹配当前位置之前必须出现的内容
反向预查 反向否定预查 Negative Lookbehind \@<! 匹配当前位置之前****不能出现的内容

注意:Vim 的正则语法与常见的 PCRE(如 Python、JavaScript 中的 (?=...))不同。Vim 将断言操作符放在被检查模式的后面


2. 详细用法与示例

A. 向前预查 (Lookahead) - 检查右边

用于判断当前匹配内容的后面是什么。

  • 正向 (\@=)

    • 场景:匹配后面跟着 "bar" 的 "foo"。
    • Vim 正则foo$bar$\@=
    • 解释:匹配 "foo",前提是它后面紧跟着 "bar"。最终只选中 "foo"。
    • 对比 PCRE: foo(?=bar)
  • 负向 (\@!)

    • 场景:匹配后面跟着 "bar" 的 "foo"。
    • Vim 正则foo$bar$\@!
    • 解释:匹配 "foo",前提是它后面不是 "bar"。
    • 对比 PCRE: foo(?!bar)

B. 向后预查 (Lookbehind) - 检查左边

用于判断当前匹配内容的前面是什么。

  • 正向 (\@<=)

    • 场景:匹配前面是 "foo" 的 "bar"。
    • Vim 正则$foo$\@<=bar
    • 解释:匹配 "bar",前提是它前面紧跟着 "foo"。最终只选中 "bar"。
    • 对比 PCRE: (?<=foo)bar
  • 负向 (\@<!)

    • 场景:匹配前面是 "foo" 的 "bar"。
    • Vim 正则$foo$\@<!bar
    • 解释:匹配 "bar",前提是它前面不是 "foo"。
    • 对比 PCRE: (?<!foo)bar

3. 重要注意事项

  1. 位置差异

    • 通用正则(PCRE):操作符在括号,如 (?=pattern)
    • Vim:操作符在括号,如 $pattern$\@=
    • 记忆技巧:Vim 的逻辑是“先写出要检查的模式 $pattern$,然后声明对这个模式进行什么操作 \@=”。
  2. 定长限制 (Lookbehind only)

    • 在旧版本的 Vim 或某些配置下,向后预查\@<=\@<!)内部的模式必须是定长的(Fixed width)。
    • 例如:$ab$\@<=c 是合法的(长度为2)。
    • 例如:$a*$\@<=c 通常是非法的(因为 a* 长度不定),但在较新的 Vim 版本(支持无限回溯引擎时)可能允许,或者需要使用 \& 等技巧变通。如果报错,请尝试重写逻辑或使用向前预查。
  3. 组合使用
    你可以组合多个预查来实现复杂逻辑。

    • 例子:匹配既不在 "start" 后也不在 "end" 前的 "middle"。
    • $start$\@<!middle$end$\@!

4. 快速总结表

你想检查... 条件是“必须有” 条件是“不能有”
右边 (后面) $pattern$\@= $pattern$\@!
左边 (前面) $pattern$\@<= $pattern$\@<!

这些关键字是 Vim 高级文本处理(如复杂的查找替换 :s 或高亮匹配 :match)的核心工具。

posted @ 2026-03-10 17:26  庶旁  阅读(1)  评论(0)    收藏  举报