Morgan Laco
Morgan Laco

Reputation: 160

Avoid repeating regex substitution

I have lines of code (making up a Ruby hash) with the form of:

"some text with spaces" => "some other text",

I wrote the following vim style regex pattern to achieve my goal, which is to replace any spaces in the string to the left of the => with +:

:%s/\(.*\".*\)\ (.*\"\ =>.*\,)/\1+\2

Expected output:

"some+text+with+spaces" => "some other text",

Unfortunately, this only replaces the space nearest to the =>. Is there another pattern that will replace all the spaces in one run?

Upvotes: 0

Views: 112

Answers (2)

FDinoff
FDinoff

Reputation: 31419

Rather than write a large complex regex a couple of smaller ones would easier

:%s/".\{-}"/\=substitute(submatch(0), ' ', '+', 'g')

For instance this would capture the everything in quotes (escaped quotes break it) and then replace all spaces inside that matched string with pluses.

If you want it to work with strings escaped quotes in the string you just need to replace ".\{-}" with a slightly more complex regex "\(\\.\|[^\"]\)*"

:%s/"\(\\.\|[^\"]\)*"/\=substitute(submatch(0), ' ', '+', 'g')

If you want to restrict the lines that this substitute runs on use a global command.

:g/=>/s/"\(\\.\|[^\"]\)*"/\=substitute(submatch(0), ' ', '+', 'g')

So this will only run on lines with =>.

Relevant help topic :h sub-replace-expression

Upvotes: 2

yolenoyer
yolenoyer

Reputation: 9445

It's really far from perfect, but it does nearly the job:

:%s/\s\ze[^"]*"\s*=>\s*".*"/+/g

But it doesn't handle escape quotes, so the following line won't be replaced correctly:

"some \"big text\" with many spaces" => "some other text",

Upvotes: 1

Related Questions