这是一个正则表达式问题。在这种情况下,我使用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”匹配的正则表达式?
答案 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