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

时间:2017-07-30 18:23:10

标签: regex vim negative-lookahead

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

说我想要更换"掉线"与"后果"在以下示例中:

  • 他们担心核衰退和辐射。
  • 有摔倒,然后是那里的辐射。
  • 在长崎,最大的担忧之一就是失败了。
  • 2000年代最好的游戏之一是#34;掉线"。

反例:

  • 那不属于你的职权范围。

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

fall out[^a-z]

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

人们通常如何处理这个问题,以及如何在比赛中保留上下套管?

1 个答案:

答案 0 :(得分:5)

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

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

对于案例问题,您可以使用捕获组(请参阅:h /\()来捕获fallout,以便您可以在替换的替换部分中引用它们命令。

它会给:

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

分解一点:

             ┌──────── capture `fall`
             │       ┌ capture `out`
        ┌────┤   ┌───┤
%s/\v\c<(fall)\s+(out)>/\1\2/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启用非常神奇的模式。没有它,你将不得不在模式中逃脱几个原子/量词。

编辑:

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

:%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