Vim:如何替换字符串的多个实例,但仅替换该字符串内的某些定界符之间

时间:2019-03-26 22:45:22

标签: regex vim

这是一个正则表达式问题。在这种情况下,我使用Vim来完成这项工作,但在其他时候使用其他种类的regex,我会对regex部分的一般答案感兴趣。

考虑以下示例,我想用一些其他文本“ cd”替换一些任意文本字符串“ ab”,但前提是它出现在单词START和END之间:

Before:
 ab ab ab START ab ab ab END ab ab ab

I would like this to become:
 ab ab ab START cd cd cd END ab ab ab

在我要替换的字符串“ ab”之间可能还有其他单词/文本。不知道字符串“ ab”在“ START”之前,“ START”和“ END”之间以及在“ END”之后出现了多少次。它可能根本不会出现。

我希望不要在START和END分隔符处拆分每一行,仅在该行上执行全局s / ab / cd / g,然后重新加入这些行。是否存在仅与分隔符之间的“ ab”匹配的正则表达式?

2 个答案:

答案 0 :(得分:3)

:%s/START\zs.*\zeEND/\=substitute(submatch(0), 'ab', 'cd', 'g')/
  • \zs\ze的宽度为零,不匹配任何内容。它们简单地表示比赛的开始结束
  • \=使我们可以使用:h function-list命令中的任何表达式(因此也可以使用:s中的任何函数)。
  • submatch(0)包含我们刚刚匹配的字符串。
  • 然后我们substitute() ab cd出现的所有:h /zero-width :h /\zs :h /\ze :h sub-replace-expression :h submatch() :h substitute()

这是一种可以以多种方式使用的标准模式。

帮助:

Left join

答案 1 :(得分:0)

不考虑正则表达式的可能性,可以在可视块选择内使用替换(选择要替换的块),然后:

:'<,'>s/\%Vab/cd/g

说明

'<,'> ............. refers to the visual block
s/ ................ substitution
\%V ............... that's the trick, it restricts the substitution
ab ................ old pattern
cd ................ new pattern
g  ................ globally

有关更多信息,请参见::h /\%V