用于替换引号内空格的vim正则表达式

时间:2010-06-04 13:58:34

标签: regex vim

我有以下格式的文字:

ERR_OUT_OF_MEM, "ERR OUT OF MEM"
ERR_SOMETHING_BAD, "ERR SOMETHING BAD"

我想用下划线替换文本中带引号的所有空格:

 ERR_OUT_OF_MEM, "ERR_OUT_OF_MEM"
 ERR_SOMETHING_BAD, "ERR_SOMETHING_BAD"

我能想到的最好的正则表达式是:

\("\w\+\)\@<= 

(最后有一个空格)

但是这只找到每个引用字符串中的第一个空格,我需要多次重复这个以获得所需的效果。

任何方式一次性做到这一点?

谢谢!

3 个答案:

答案 0 :(得分:7)

肯定有一个0长度模式可以一次通过,但由于我从未使用过它们,我更喜欢这种方法:

:%s/\%("[^"]*"\)*\("[^"]*"\)/\=substitute(submatch(1), ' ', '_', 'g')/g

注意:双引号保持2对2分组,以便不转换

foo bar "foo bar" "foo barr"

进入

foo bar "foo_bar"_"foo_barr"

编辑:正如猖獗指出的那样,以下绰绰有余:

%s/"[^"]*"/\=substitute(submatch(0), ' ', '_', 'g')/g

答案 1 :(得分:6)

这不是一个通用的解决方案,因为它会匹配一行中双引号后出现的任何空格,但它应该适用于您指定格式的字符串:

s/\v(\".*)@<= /_/g

我使用了\ v(verymagic)令牌,因为我认为它使正则表达式更具可读性,并且我包含了整个替换命令,因为最后的'g'很重要。

对于那些在家中跟随的人,这个正则表达式首先用\ v设置'verymagic'模式。然后它定义了令牌(\".*),它大致意味着“双引号,然后是其他任何东西”,并使用lookbehind断言@<=来说“只匹配最后一个令牌之后的东西” - 换句话说,只匹配双引号之后出现的事情。最后,有一个空间,实际上是匹配的,替换术语是下划线,这是我们想要替换它的内容,g说“替换所有匹配的术语”所以我们不这样做刚刚找到第一场比赛。

答案 2 :(得分:0)

我的PatternsOnText plugin提供:SubstituteInSearch命令。有了它,您首先搜索引用的字符串,然后仅在匹配项中执行:substitute

/".\{-}"
:SubstituteInSearch/_/ /g