我可以使:s仅在该行的最后一个匹配项上运行吗?


16

:s/pattern/replacement在第一个比赛和:s/pattern/replacement/g所有比赛中 进行操作。

如何仅对最后一个进行操作?

Answers:


18

我会用 \zs

:%s/.*\zspattern/replacement/

一点解释:

  • . 代表任何单个字符
  • * 表示贪婪匹配(尽可能多)

在Vim中,可以使用零宽度的定位符,\zs\ze定义要匹配的搜索模式的开始和结束。模式之前\zs和之后的所有内容\ze都不会受到替换的影响。

为了易于理解,我想使用wikiaSearch and replace中的示例:

使用\zs\ze设置模式的开始和结束以保存键入。例如,代替:

:s/Copyright 2007 All Rights Reserved/Copyright 2008 All Rights Reserved/ 

采用:

:s/Copyright \zs2007\ze All Rights Reserved/2008/

有关更多信息,请参见


您能否提供\zs答案的基本描述?
EvergreenTree

3
值得一提的是,之所以这个作品是因为.*贪婪
通配符

7

您可以通过将所有分组\(.*\)(但最后一次出现)分组来搜索最后一个匹配项pattern。然后退出与捕获的组\1,并添加replacement

:%s/\(.*\)pattern/\1replacement/

(这比@ryuichiro的\zs解决方案逊色,因为您的\1方法在功能上是等效的,但更冗长。(另一方面,某些方法可能更容易记住,尤其是如果它们习惯于其他正则表达式)。)
Aaron Thoma 2016年

0

为了完整起见,我想我会发布一个替代方案。Vim有多个项目,其中一些类似于更标准的正则表达式环顾断言(负/正向超前/向后看)。/programming/2973436/regex-lookahead-lookbehind-and-atomic-groups

在这种情况下,我们希望有一个负先行,\@!,这意味着我们要断言原子先于该项目不发生后的图案。在这种情况下,原子本身就是模式之前的其他任何形式:

:%s/pattern\(.*pattern\)\@!/replacement/

括号内的部分为零宽度,不包含在匹配项中,因此不会被替换代替。

:h \@!以获得更多信息,或:h pattern-multi-items获得包含其他环视变化的整个部分。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.