如何在vim中非捕获搜索和替换

时间:2016-03-24 19:47:40

标签: regex vim

我正在尝试学习如何在vim中使用正则表达式,而我目前正在尝试进行搜索和替换。我有这样的事情:

aaaaaaa&sometext&...
aaaaaaaanothertext

a s实际上是该行开头的空格,我不知道如何在这里打印出来。

我希望将&的第一次出现替换为& &,并按原样保留其他所有内容。我按照建议here使用\%(...\)非捕获模式,但仍然捕获了a模式。我使用:%s/\%(^a*\)&/& &/gc,我得到了:

aaaaaaaa& aaaaaaaa&sometext&...
aaaaaaaaanothertext

我不明白为什么。我也尝试过替换群组,例如:%s/\%(^a*\)\(&\)/\1 \1/gc,但后来我得到了:

& &sometext&...
aaaaaaaanothertext

因此,似乎群组处理确实被忽略(因为第一组在搜索模式上是&),但仍然在搜索模式上捕获。

所以,长话短说,我必须使用替换命令:

aaaaaaa&sometext&...

为:

aaaaaaa& &sometext&...

3 个答案:

答案 0 :(得分:6)

  

我想将&的第一次出现替换为& &,并保留   其他一切都是

使用替换命令:

:s/&/& &/

另一个提示:默认情况下,Vim将(视为文字字符,而不是组的开头。

如果您希望正则表达式更像传统(Perl)正则表达式,请使用very magic模式。

指定very magic模式的简便方法是使用\v启动正则表达式:

" this is a no-op
:s/\v(this is grouped)/\1/
编辑:这个答案有效,但请参阅@ heijp06以下非常相关的评论(我不知道&字符有特殊意义。)

评论粘贴在这里:

  

为什么这个答案是正确的,实际上有点不重要。一个&在   替换的替换部分意味着匹配的东西   在这种情况下的模式是&所以最终效果是正确的。

答案 1 :(得分:4)

“非捕获”并不代表您认为的含义。 \(...\)\%(...\)之间的唯一区别在于子表达式是否已保存到\1\2 ...它仍将包含匹配中匹配的内容。< / p>

您想要\@<=:help \@<=):

:s/\(^a*\)\@<=&/\& \&/g

答案 2 :(得分:0)

通常在搜索和替换中,替换项完全替换搜索就足够了。在这种情况下,您的搜索将包括您不想替换的内容。

Vim具有有用的模式来定义比赛的开始和结束:\zs\ze。您可以将\zs放在搜索中的任何位置,vim仅在开始之后匹配。您可以使用两者来说,找到此特定行,而只替换其中一部分。

解决方法:

:%s:^[^&]*\zs&:& &:c

  • %s:查看文件中的每一行
  • ^[^&]*:从该行的开头开始,应该为零或多个 not &
  • \zs&:要替换的匹配项是单个&
  • & &:将匹配项替换为两个&
  • c:在我对正则表达式感到厌烦的情况下,以交互方式执行每个替换