:s/pattern/replacement
在第一个匹配项上运行,:s/pattern/replacement/g
在所有匹配项上运行。如何仅在最后一个匹配项上运行?
#1 楼
我会使用\zs
:%s/.*\zspattern/replacement/
一点解释:
.
代表任何单个字符*
表示贪婪匹配(尽可能多)在Vim中,您可以使用零宽度锚点
\zs
和\ze
定义搜索模式的开始和结束,希望匹配。模式中\zs
之前和\ze
之后的任何内容都不会受到替换的影响。为了易于理解,我想使用Wikia搜索和替换中的以下示例:
通过使用
\zs
和\ze
设置模式的开始和结束来保存键入。例如,代替:
:s/Copyright 2007 All Rights Reserved/Copyright 2008 All Rights Reserved/
使用:
:s/Copyright \zs2007\ze All Rights Reserved/2008/
有关更多信息,看看
:h \zs
:h pattern-overview
#2 楼
您可以通过将所有\(.*\)
分组,但将最近一次出现的pattern
分组来搜索最后一个匹配项。然后与捕获的组
退出,并添加replacement
。:%s/\(.*\)pattern/replacement/
评论
(这比@ryuichiro的\ zs解决方案逊色,因为您的\ 1方法在功能上是等效的,但是更冗长。(另一方面,对于某些方法,可能更容易记住,尤其是当它们习惯于其他正则表达式时)。 ))
–亚伦·托马
16/12/30在1:44
#3 楼
为了完整起见,我认为我会发布一个替代方案。 Vim有多个项目,其中一些类似于更标准的正则表达式环顾断言(负/正向超前/向后看)。 https://stackoverflow.com/questions/2973436/regex-lookahead-lookbehind-and-atomic-groups在这种情况下,我们想要一个负的前瞻
\@!
,这意味着我们想断言原子模式之前不会发生在项目之前的内容。在这种情况下,原子本身就是模式之前的其他任何形式::%s/pattern\(.*pattern\)\@!/replacement/
括号内的部分为零宽度,不包含在匹配项中,因此不会被替换
:h \@!
以获得更多信息,或:h pattern-multi-items
包含其他环视变化的整个部分。
评论
您能否提供\ zs答案的基本描述?
–EvergreenTree
2015年10月13日在17:59
值得注意的是,此功能起作用的原因是因为*是贪婪的。
–通配符
16 Mar 25 '16 at 0:24