1

I would like to have a regular expression that replace:

"foo" "bar" Is "hello" "world" "!"

by:

"foo" "bar" Is "hello world !"

I have tried :%s/Is\(\s*"\([^"]*\)"\)*/Is "\2\4\6"/

But it seems that \2 is the last capture of the second group (!) and it returns:

Is "!"

Is there a way to do that in Vim?

6
  • 2
    This works for your example: :s/" "/ /g
    – mattb
    Commented Apr 1, 2022 at 17:07
  • Indeed but my real problem is actually slightly different I want to do the replacement only if the list of quoted string is prefixed by a the keyword: Is. I have updated the question to encompass its full complexity. Commented Apr 1, 2022 at 17:17
  • 1
    I don't see from the updated example what the problem is... From your comment, it sounds like you want to apply a substitution command only on lines that begin with the word 'Is'. In that case, you can use the following: :g/^Is/s/" "/ /g
    – mattb
    Commented Apr 1, 2022 at 18:31
  • Good idea, but what is I would have "foo" "bar" is "hello" "world" "!" and only want the conversion applied on the second part: "hello" "world" "!"? Commented Apr 1, 2022 at 18:48
  • 2
    Ah ok, you should put this example in your question (it's different than what you have there now). I can't think of an easy way at the moment - but there are people better at this than me :) Also see this and this
    – mattb
    Commented Apr 1, 2022 at 19:27

2 Answers 2

1

As mattb pointed correctly the answer is:

:s/\(is.*\)\@<="\s\+"/ /g

1

One way to accomplish this task is to use the :s regexp to skip the initial part (Is , in your case) and then use the substitute() function to make multiple substitutions in the replacement.

In the pattern, you can use the \zs marker to start matching only after the part you want to skip (so you don't need to take care of repeating the Is in your replacement.)

In the replacement, you can use \= to introduce a Vimscript expression (which will allow you to call the substitute() function), and then you can use submatch(0) to access the contents of the pattern that matched the :s command (which is where you want the substitutions to happen.)

Putting it all together:

:s/Is \zs.*/\=substitute(submatch(0), '"\s\+"', ' ', 'g')/
1
  • 1
    Thanks. It works too. Commented Apr 4, 2022 at 7:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.