vim:用相同数量的新字符串替换子匹配

时间:2017-07-25 17:03:54

标签: vim

我的计划是做一个非常标准的搜索替换,用old_string替换new_string的所有实例。问题是我只想在特定old_strings之后为任意数量的prefix执行此操作。例如:

old_string = "a"
new_string = "b"
prefix = "xxxx"

xxxxaaaaaaaa => xxxxbbbbbbbb
xxxxaaapostfix => xxxxbbbpostfix
xxaaaa => xxaaaa

等。我不知道该怎么做。我想有一些方法可以说s/xxxxa*/xxxxb{number of a's}/g或其他什么,但我不知道它是什么。

2 个答案:

答案 0 :(得分:5)

你绝对可以做到这一点!我会使用\=寄存器来评估一些vimscript。来自:h s/\=

Substitute with an expression           *sub-replace-expression*
                        *sub-replace-\=* *s/\=*
When the substitute string starts with "\=" the remainder is interpreted as an
expression.

The special meaning for characters as mentioned at |sub-replace-special| does
not apply except for "<CR>".  A <NL> character is used as a line break, you
can get one with a double-quote string: "\n".  Prepend a backslash to get a
real <NL> character (which will be a NUL in the file).

然后,您可以使用repeatsubmatch函数构建正确的字符串。例如:

:%s/\(xxxx\)\(a\+\)/\=submatch(1).repeat('b', len(submatch(2)))

我选择使用\+而不是*,因为在替换命令完成后将找不到该模式(此效果hlsearch n

当然,如果你使用\zs\ze(匹配的开始/结束)原子,你可以使用更少的捕获组,这使得这个更短更清晰。

:%s/xxxx\zsa\+/\=repeat('b', len(submatch(0)))

答案 1 :(得分:1)

如果您有perl支持,则可以使用

:%perldo s/xxxx\Ka+/"b" x length($&)/ge
  • xxxx\Ka+仅在前面有a
  • 时才与一个或多个xxxx匹配
  • 使用\ K
  • 看后面
  • /ge替换所有匹配项,e允许在替换部分中使用Perl代码
  • "b" x length($&)字符串b重复length($&)

有关详细信息,请参阅:h perl