我有以下格式的文字:
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\+\)\@<=
(最后有一个空格)
但是这只找到每个引用字符串中的第一个空格,我需要多次重复这个以获得所需的效果。
任何方式一次性做到这一点?
谢谢!
答案 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