我正在尝试学习如何使用vim的正则表达式,我正在尝试进行搜索和替换.我有这样的事情:
aaaaaaa&sometext&...
aaaaaaaanothertext
Run Code Online (Sandbox Code Playgroud)
(as实际上是行开头的空格,我不知道如何在这里打印)
我想替换第一次出现的&有& &,并保持everyting其他不变.我正在使用\%(...\)非捕获模式,如此处所示,但a模式仍然被捕获.我正在使用:%s/\%(^a*\)&/& &/gc,我得到:
aaaaaaaa& aaaaaaaa&sometext&...
aaaaaaaaanothertext
Run Code Online (Sandbox Code Playgroud)
我不明白为什么.我也尝试过用组替换:%s/\%(^a*\)\(&\)/\1 \1/gc,但是后来我得到了:
& &sometext&...
aaaaaaaanothertext
Run Code Online (Sandbox Code Playgroud)
因此,似乎该组实际上被忽略了组处理(因为第一组是在搜索模式上&),但仍然在搜索模式上捕获.
所以,长话短说,取代命令我必须使用来自:
aaaaaaa&sometext&...
Run Code Online (Sandbox Code Playgroud)
至:
aaaaaaa& &sometext&...
Run Code Online (Sandbox Code Playgroud)
?
我想替换第一次出现
&with& &,并保持其他所有内容
使用替换命令:
:s/&/& &/
Run Code Online (Sandbox Code Playgroud)
另一个提示:默认情况下,Vim视为(文字字符,而不是组的开头.
very magic如果您希望正则表达式更像传统(Perl)正则表达式,请使用模式.
指定very magic模式的简单方法是使用以下命令启动正则表达式\v:
" this is a no-op
:s/\v(this is grouped)/\1/
Run Code Online (Sandbox Code Playgroud)
编辑:这个答案有效,但请参阅下面的@ heijp06非常相关的评论(我不知道该&角色有特殊含义).
评论贴在这里:
实际上这个答案是正确的,这实际上有点不同寻常.替换的替换部分中的&替换意味着在这种情况下与模式匹配的那样的结果是正确的.
“非捕获”并不意味着您认为的含义。\(...\)和之间的唯一区别\%(...\)是子表达式是否保存到\1,\2...仍将匹配项包含在匹配项中。
您想要\@<=(:help \@<=):
:s/\(^a*\)\@<=&/\& \&/g
Run Code Online (Sandbox Code Playgroud)
通常在搜索和替换中,替换完全替换搜索就足够了。在这种情况下,您的搜索将包括您不想替换的内容。
Vim 有一些有用的模式来定义匹配的开始和结束:\zs和\ze。你可以放在\zs搜索的任何地方,vim 只会在开始后匹配。您可以使用两者来表示,找到该特定行并仅替换其中的一部分。
以及解决方案:
:%s:^[^&]*\zs&:& &:c
%s: 查看文件中的每一行^[^&]*:从行首开始,应该有零个或多个不 & \zs&:要替换的匹配是单个& & &:将匹配项替换为两个& c:交互地执行每个替换,以防我在正则表达式上表现不佳