vim regex for replacing spaces within quotes

*爱你&永不变心* 提交于 2019-12-21 12:29:22

问题


I have text in the follwing format:

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

I want to replace all spaces in the text which are within quotes with underscores:

 ERR_OUT_OF_MEM, "ERR_OUT_OF_MEM"
 ERR_SOMETHING_BAD, "ERR_SOMETHING_BAD"

The best regex I could come up with is:

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

(there's a space at the end of that)

but this only finds the first space in each quoted string, and I would need to repeat this multiple times to get the desired effect.

Any way to do it in one shot?

Thanks!


回答1:


There is certainly a 0-length pattern that works in one pass, but as I never have much success using them, I prefer this kind of approach:

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

Note: double-quotes are kept grouped 2 by 2 in order to not transform

foo bar "foo bar" "foo barr"

into

foo bar "foo_bar"_"foo_barr"

EDIT: as rampion pointed out, the following is more than enough:

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



回答2:


This isn't a general-purpose solution, since it will match any space that appears anywhere after a double quote on a line, but it should work for strings in the format you've specified:

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

I've used the \v (verymagic) token because I think it makes the regex a little more readable, and I included the whole substitution command, since the 'g' at the end is important.

For those following along at home, this regex first sets 'verymagic' mode with \v. Then it defines the token (\".*) which roughly means "a double quote and then anything else" and uses the lookbehind assertion @<= to say "only match things following that last token" - in other words, only match things that come somewhere after a double quote. Finally, there's a space, which is what actually gets matched, and the substitution term is an underscore, which is what we want to replace it with, and the g says "substitute all matching terms" so we don't just get the first match found.




回答3:


My PatternsOnText plugin provides a :SubstituteInSearch command. With it, you first search for the quoted strings, then perform a :substitute only within the matches:

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


来源:https://stackoverflow.com/questions/2974768/vim-regex-for-replacing-spaces-within-quotes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!