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

vic*_*dev 7 regex vim

我有以下格式的文字:

ERR_OUT_OF_MEM, "ERR OUT OF MEM"
ERR_SOMETHING_BAD, "ERR SOMETHING BAD"
Run Code Online (Sandbox Code Playgroud)

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

 ERR_OUT_OF_MEM, "ERR_OUT_OF_MEM"
 ERR_SOMETHING_BAD, "ERR_SOMETHING_BAD"
Run Code Online (Sandbox Code Playgroud)

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

\("\w\+\)\@<= 
Run Code Online (Sandbox Code Playgroud)

(那里有一个空间)

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

有什么办法一次性完成吗?

谢谢!

Luc*_*tte 7

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

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

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

foo bar "foo bar" "foo barr"
Run Code Online (Sandbox Code Playgroud)

foo bar "foo_bar"_"foo_barr"
Run Code Online (Sandbox Code Playgroud)

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

%s/"[^"]*"/\=substitute(submatch(0), ' ', '_', 'g')/g
Run Code Online (Sandbox Code Playgroud)


Joh*_*and 6

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

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

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

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