7

如何在结果字符串中精确重复 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,但如果文本的其余部分有一个“+”,我只会把它搞砸。

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

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

谢谢

4

3 回答 3

8

尝试这个:

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

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

了解更多信息:

:help sub-replace-expression
:help repeat()
:help submatch()
:help strlen()
于 2012-08-07T13:26:06.243 回答
3

对于这种情况,一个优雅的替换命令如下:

:%s/\%(^+*\)\@<=+/   /g
于 2012-08-07T14:29:02.390 回答
1

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

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

'^(\s*)+'

替换为(再次减去单引号)

'$1   '

不是每个可以用正则表达式解决的问题都可以只用一个正则表达式来解决——我很确定这是其中一种情况

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

于 2012-08-07T13:22:40.237 回答