在Vim中只查找和替换单行的一部分

Sco*_*ott 6 vim

在vim大多数替代命令执行在一个完整的行或一组线的作用,但我想只要这样做上的线(从光标到行的结束或之间组标记)的一部分.

this_is_a_sentence_that_has_underscores = this_is_a_sentence_that_should_not_have_underscores
Run Code Online (Sandbox Code Playgroud)

this_is_a_sentence_that_has_underscores = this is a sentence that should not have underscores
Run Code Online (Sandbox Code Playgroud)

这项任务对于整条生产线来说非常容易:s/_/ /g,但是在执行任务之后只执行替换任务似乎要困难得多=.

可以:substitution在一半线上执行操作吗?

glt*_*lts 8

我能想到的两种解决方案.

选项一,使用前/后列匹配原子\%>123c\%<456c.

在您的示例中,以下命令仅在第42列和第94列之间的第二个单词中替换下划线:

:s/\%>42c_\%<94c/ /g
Run Code Online (Sandbox Code Playgroud)

选项二,使用Visual area match atom \%V.

在您的示例中,Visual-选择第二个长字,离开可视模式,然后执行以下替换:

:s/\%V_/ /g
Run Code Online (Sandbox Code Playgroud)

这些正则表达式原子分别记录在:h /\%c:h /\%V.


Pet*_*ker 5

环视四周

您的帖子已经有很大的线索:

只能在之后更换任何东西=

这通常意味着使用正向后看\@<=

:%s/\(=.*\)\@<=_/ /g
Run Code Online (Sandbox Code Playgroud)

这意味着匹配_以下模式之后的所有内容=.*。由于所有环顾处(先行和后备)均为零宽度,因此它们在比赛中不会占用空间,并且替换非常简单。

注意:这相当于(?<=...)在perl中讲。请参阅:h perl-patterns

\zs

\zs将在特定点设置比赛开始。从表面上看,这确实是需要的。但是\zs,由于它与\zs第一个然后是下一个模式之前的模式匹配,因此无法正常工作。这意味着将只有一场比赛。另一方面,“向后看”匹配该零件,\@<=然后“向后看”以确保匹配有效,这非常适合多个替换方案。

应该注意的是,如果可以使用,\zs不仅打字容易,而且效率更高。

注意:\zs就像\K在perl中说话一样。

更多方法?!?

正如@glts提到的,您可以使用其他零宽度原子来基本“锚定”您的图案。几种常见方式的列表:

  • \%>a- 'a标记后
  • \%V -在视觉区域内匹配
  • \%>42c -栏后匹配 42

使用这些方法之一的可能弊端是它们需要您设置标记或计数列。这没有什么错,但是这意味着替换可能会受到副作用的影响,因此重复替换可能无法正常进行。

有关更多帮助,请参见:

:h /\@<=
:h /zero-width
:h perl-patterns
:h /\zs
Run Code Online (Sandbox Code Playgroud)