在Vim中用相同字符替换正则表达式匹配中的所有字符

24

我有一个正则表达式,可以用特定的字符串替换匹配到的模式,其中这个字符串是通过重复某个字符直到字符数与匹配到的模式相同而动态构建的。

例如,假设我有以下替换命令:

%s/hello/-----/g

但是,我希望做的是这样的:

%s/hello/-{5}/g

不存在的记号-{5}表示重复出现五次的破折号。

有没有办法实现这个?

最终,我想要实现类似这样的效果:

%s/(hello)*/-{\=strlen(\0)}/g

这将替换任何仅由字符串hello组成的实例,使用破折号字符重复匹配的字符串长度次数的字符串。

2个回答

38
%s/\v(hello)*/\=repeat('-',strlen(submatch(0)))/g

可以了!谢谢。你知道在哪里可以找到所有可用的函数(比如strlen和repeat)吗? - beatgammit
3
或者 function-list。有时更方便。 - sidyll
1
要了解更多相关信息,请使用 :help sub-replace-special:help sub-replace-expression - Benedikt Köppel

6
作为使用 :substitute 命令的替代方案(其用法已在 @Peter 的答案中涵盖),我建议通过自引用宏来自动执行编辑命令以进行替换。
手动覆盖搜索模式出现的字符的简单方法是使用以下一系列 Normal 模式命令。
  1. Search for the start of the next occurrence.

    /\(hello\)\+
    
  2. Select matching text till the end.

    v//e
    
  3. Replace selected text.

    r-
    
  4. Repeat from step 1.

因此,为了自动化这个例程,可以运行命令:
:let[@/,@s]=['\(hello\)\+',"//\rv//e\rr-@s"]

执行来自缓冲区(或其他适当位置)起始处的s寄存器的内容。
gg@s

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接