如何在结果字符串中精确重复n个匹配的模式

时间:2012-08-07 13:11:21

标签: regex vim

如何在结果字符串中精确重复n个匹配的模式?

示例如果我有以下文字:

++ '[' -f /etc/bashrc ']'
++ . /etc/bashrc
+++ '[' '[\u@\h \W]\$ ' ']'
+++ '[' -z 'printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"' ']'
+++ shopt -s checkwinsize
+++ '[' '[\u@\h \W]\$ ' = '\s-\v\$ ' ']'
+++ shopt -q login_shell
+++ '[' 506 -gt 199 ']'
++++ id -gn

现在我想用每个'+'代替3个空格,但它只能在模式的开头发生。我会使用:<range>s/^<pattern> :%s/+/ /g,但如果在文本的其余部分中有“+”,我就会搞砸它。

问题: 如何在开始时匹配每个+并在结果字符串中重复相同的found +数? 预期:

^   ++$  -> ^         $
^   +++$ -> ^            $
^   +$   -> ^      $

由于

3 个答案:

答案 0 :(得分:8)

试试这个:

:%s/^+*/\=repeat('   ',strlen(submatch(0)))/

submatch(0)包含该行开头的所有匹配+strlen计算它们。因此,对于行开头的每个加号,使用repeat插入三个空格。

了解更多信息:

:help sub-replace-expression
:help repeat()
:help submatch()
:help strlen()

答案 1 :(得分:3)

此案例的优雅替换命令如下。

:%s/\%(^+*\)\@<=+/   /g

答案 2 :(得分:1)

我认为你必须多次运行一个表达式,如果这是可以接受的......

你想要运行这样的东西(减去单引号,用于显示空格):

'^(\s*)+'

替换为类似的东西(再次减去单引号)

'$1   '

并非所有可以使用正则表达式解决的问题都只能使用一个正则表达式来解决 - 我很确定这是其中一种情况

这个表达式/替换对将需要在行开头的每个加号运行一次,加号最多(在上面的示例中,这将是四次)注意:如上所述,这将搞乱任何应该以空格和加号开头的行,所以我希望在任何地方都不会发生...