Vim:替换一行中除最后一个点以外的所有点

8
我正在寻找一种方法,以替换一行中除最后一个点外的所有点。
例如: "Blah - whatever - foo.bar.baz.avi" 应变为 "Blah - whatever - foo bar bar.avi"
由于文件中有多行且每行中点的数量不同,因此我需要通用解决方案,而非将X个匹配项替换为常量"Replace the first X matches"。

是的,我想用空格替换所有点,除了文件名和扩展名之间的那个点。 - ThiefMaster
3个回答

12

这似乎可以解决问题:

%s/\.\(.*\.\)\@=/ /g

\@= 是一个前瞻(lookahead)匹配项。它只在后面有任何跟随的句点时才匹配句点本身。

参见:help zero-width


哦,Vim 中的向前查找语法等非常难看。我想知道为什么他们没有使用 PCRE 等语法。 - ThiefMaster
@ThiefMaster:是的...我很困惑这个模式必须位于前瞻 "运算符" 的前面...但是不管怎样,它们非常方便 :) - Felix Kling
1
@ThiefMaster 试试使用 Perl5 正则表达式的 :perldo s/searchme/replaceme/g 命令?另外,这里有一个链接:http://vim.wikia.com/wiki/Perl_compatible_regular_expressions - sehe

7
作为第一个答案的替代,您可能更喜欢这种语法:
%s/\.\ze.*\./ /g

它允许您在搜索运算符后放置断言,即必须有一个句号。


0

另一种可能有用的学习方法(替换视觉选择内部)是:
:g/^/normal $F.hv0:s/\%V\./ /g^M
其中,^M是通过按下CTRL-VEnter输入的。

这意味着:对于每一行(g/^/),键入$F.(到最后一个点),从左侧字符开始到行首进行可视化选择(hv0),然后仅在可视化选择内部替换点(:s/\./ /g^M)(\%V)。


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