3

I want to replace all adjacent spaces with one space but the replacement should only take place if they aren't at the line begin.

For example (I use brackets to demarcate line begin and end):

[Hello,     world!   ]

should be replaced with

[Hello, world! ]

but

[     Hello,     world!   ]

should become:

[     Hello, world! ]

I've tried the following command:

.s/\v([^\s])(\s){2,}/\1\2/g

But it replaces leading spaces too. I'm not sure why it's applied to leading spaces. Because I explicitly tell vim to replace only those adjacent spaces who follow a non-whitespace character ...[^\s]...

Or is the line begin character ^ considered as a character and I've to involve it either? Ok, I also tried this one but without success:

.s/\v([^\s^])(\s){2,}/\1\2/g

So I'm lost here...

1 Answer 1

4

\s doesn't work in []. It seems that only \t works. Weird, right?

Instead, \S is the opposite of \s. Use this:

:s/\S\zs\s\+/ /g

It substitute all whitespaces following a non-whitespace character with one space. \zs restarts the match so \S is not replaced.


I also figured out a hard way to retain the type of whitespace (tab or space):

:s/\v(^\s*\S.{-})@<=(\s)\2+/\2/g

@<= is like \zs with a little difference. ^\s* matches leading whitespaces.

\2 is the same as \s: If \s matches tab, then \2 must be tab, no space, and vice versa.

Your Answer

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

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