首页 > 解决方案 > 如何替换gvim中所有不以破折号开头的单词?

问题描述

我有一个文本文件,其模式如下:

-a a -b b -c c -d d

我想替换所有不以 . 开头的-单词z。所以预期的文本是

-a z -b z -c z -d z

我试过%s/^(-\(.*\))/z/g了,但这似乎取代了一切。

标签: vim

解决方案


这里的第一个问题是*(参见:h /star,其中说Matches 0 or more of the preceding atom, as many as possible.)的贪婪。

问题指出只有单词需要替换,所以我们使用单词 atom \w。我们不能使用

" don't use
:%substitute/[^-]\w\+/z/g

因为[^-]匹配一个字符,包括空格,并且破坏了一些东西。

我们认为我们需要一个消极的回顾:

" don't use this either
:%substitute/-\@!\w\+/z/g

现在,问题是aaa-aaa匹配中:第一个a不是 a -,所以 vim 很高兴地说这是一个 match

所以我们要做非正则表达式。

这个想法是搜索-\w\+,然后跳到下一个单词并进行更改(这在很大程度上基于输入模式):

" these should be typed in normal mode
/-\w\+<ENTER>
W
ciwz<ESC>

输入这些后,您可以用 完成整个文件nW.,但这至少比我想输入的字符多一个,而且我有时讨厌 shift 键。所以我们把它变成一个宏:

qqnW.q

并使用其中之一重播任意次数

  • @q
  • @@@q至少运行一次后)
  • 100@q(我们想选择一个大的数字来覆盖整个文件)

我已经从原始正则表达式中省略了不必要的括号。我也省略了,^因为从给出的示例中,并非所有要替换的文本都在行首。见:h /^。最后,我改为*\+在实际上有单词字符开头时才匹配。


推荐阅读