正则表达式:替换正则表达式匹配的部分

Regular Expressions: Replacing Portions of a Regex Match

使用 Vim、Notepad++ 或 Sublime 我希望能够搜索和替换匹配项的 部分 。我认为这可以使用负前瞻来完成,但我想征求社区的意见。

假设我想在以下示例中用 "fallout" 替换 "fall out" 的事件:

一个反例:

我想一个明显的匹配模式是:

fall out[^a-z]

但是用这个匹配替换这里的 "fallout" 会产生不良影响,即四个正例中的逗号、space、句点和尾引号将被删除。

人们通常如何处理这个问题,还有奖金,你会如何在比赛中保留大写字母和小写字母?

虽然你可以用负前瞻做你想做的事,但我认为你不需要,你可以简单地使用零宽度原子 \>(见 :h /\>)来描述一个词的结尾。

\> 表示前一个字符是单词的最后一个(技术上是缓冲区本地选项 'iskeyword' 中的最后一个字符)。

关于大小写问题,可以使用捕获组(见:h /\()捕获fallout,这样在替换部分可以参考你的替换命令。

它会给出:

:%s/\v\c<(fall)\s+(out)>//g

稍微分解一下:

             ┌──────── capture `fall`
             │       ┌ capture `out`
        ┌────┤   ┌───┤
%s/\v\c<(fall)\s+(out)>//g
                         │ │
                         │ └─ use the text from the 2nd capturing group (will preserve the case)
                         └─ use the text from the 1st capturing group (will preserve the case)

\s+ 描述了一系列空白字符(至少一个)。 \c 将使模式不区分大小写,而 \v 启用非常神奇的模式。没有它,您将不得不转义模式中的几个 atoms/quantifier。

编辑:

实际上,您可以通过删除空格序列来简化命令:

:%s/\v\c<fall\zs\s+\zeout>//g

细分:

%s/\v\c<fall\zs\s+\zeout>//g
            │     │
            │     └─ sets the end of the match
            └─ sets the start of the match

这一次,您使用原子 \zs\ze 来设置匹配的开始和结束。有关详细信息,请参阅 :h /\zs:h /\ze