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

时间:2016-01-04 20:29:10

标签: vim

vim中的大多数替换命令对整行或一组行执行操作,但我只想在一行(从光标到行尾或设置标记之间)执行此操作。

例如

this_is_a_sentence_that_has_underscores = this_is_a_sentence_that_should_not_have_underscores

this_is_a_sentence_that_has_underscores = this is a sentence that should not have underscores

对于整行:s/_/ /g来说,这项任务非常容易,但在=之后只执行替换任何事情似乎要困难得多。

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

2 个答案:

答案 0 :(得分:8)

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

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

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

:s/\%>42c_\%<94c/ /g

选项二,使用可视区域匹配原子\%V

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

:s/\%V_/ /g

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

答案 1 :(得分:5)

环视

你的帖子已经有了很大的线索:

  

仅对=之后的任何内容执行替换。

这通常意味着使用积极的后视,\@<=

:%s/\(=.*\)\@<=_/ /g

这意味着匹配以下模式_之后的所有=.*。由于所有环视(前瞻和后视)都是零宽度,因此它们不占用匹配中的空间,并且替换很简单。

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

\zs怎么样?

\zs会在某个时间点设置匹配的开头。在脸上,这听起来恰到好处。但是\zs将无法正常工作,因为它首先匹配\zs之前的模式,然后匹配以下模式。这意味着只有一场比赛。另一方面,后视镜在\@<=之后匹配部件,然后#34;在后面看&#34;确保匹配有效,这使其适用于多种替换方案。

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

注意:\zs与perl发言中的\K类似。

更多方法?!?

正如@glts所提到的,你可以使用其他零宽度原子基本上#34;锚定#34;你的模式。一系列常见方法的列表:

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

使用这些方法之一的可能缺点是他们需要您设置标记或计数列。这没有任何问题,但这意味着替代可能会受到副作用的影响,因此重复替换可能无法正常工作。

如需更多帮助,请参阅:

:h /\@<=
:h /zero-width
:h perl-patterns
:h /\zs