2

I want to replace all occurrences in a text with ","

for example

"word1,word2,word3"

became

"word1, word2, word3"

this one is bad

:%s/,/, /g

because

"word1,word2,word3, word4"

became (note the double white space)

"word1, word2, word3,  word4"

This one delete the next letter

:%s/,[a-z]/, /gc

word1,word2...

became

word1, ord2

How to do? Thanks

4 Answers 4

4
sed -i 's/,/, /g; s/,\s\+/, /g'

You can use the exact same logic directly in Vim:

:%s/,/, /g
:%s/,\s\+/, /g

In general, I think doing things in n smaller and more intuitive steps is more efficient than wasting hours figuring out a smart and more elegant one-liner… but this is not such a case.

The following does what you want in a single take:

:%s/,\s*/, /g

The pattern matches:

  • a single comma, ,,
  • followed by zero or more whitespace characters, as many as possible, \s*,

witch covers , (because there is zero whitespace after the comma), and any variant of , , , , etc.

See :help /*.

6

While I'd do it exactly like in romainl's answer, let me point out a few pattern tricks that can make your life easier.

Your almost-solution :%s/,[a-z]/, /gc can be turned into a working solution by ending the match after the comma using the \ze (end match) atom like this

:%s/,\ze[a-z]/, /gc

This will exclude the letter following the comma from being part of the match. This is explained in :help /\ze. (Also see :help /\zs for the start match atom.)

To allow for words starting with capital letters, consider using ,\ze\S or ,\ze\w which will match non-whitespace or word characters, respectively. See :help /\S and :help /\w.

As I initially said, romainl's solution is perfect for this example. For more complex problems, these often come in handy.

2

This can be achieved using captures

:%s/,\(\w\)/, \1/g

Search for a ,, capture a word character, replace with a , followed by that same captured word character \1.

0

Actually this workaround works, but using external command

:! sed 's/,/, /g; s/,\s\+/, /g'
4
  • This solution would work in Vim as well... So why not make this a proper Vim answer? Dec 10, 2023 at 21:50
  • 1
    It would be better to write :[range]!sed <sed script> and let sed filter the input.
    – D. Ben Knoble
    Dec 11, 2023 at 1:53
  • 1
    Wouldn't sed -i need an input file, like a % appended to the line?
    – Friedrich
    Dec 12, 2023 at 11:30
  • 1
    Thanks I have correct it.
    – elbarna
    Dec 12, 2023 at 17:13

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.