3

I am trying to delete all the spaces that aren't sandwiched by a letter. So this

 I am trying; but ; I can't find a way    ;

should be this

I am trying;but;I can't find a way;

I tried this but it doesn't work.

:%s/\([A-Za-z]\)\@<! *\([A-Za-z]\)\@!//g

2 Answers 2

6

"Aren't sandwiched by a letter" means does not have: a letter before it and a letter after it, when expressed through De Morgan's laws: does not have a letter before it OR does not have a letter after it. What your regular expression is matching is does not have a letter before it AND does not have a letter after it; so it would only match between something like # ; $ (which your example does not have). Maybe it becomes clearer when we condense the collection to /\a and remove the superfluous grouping:

/\a\@<! \+\a\@!/

I've also changed * to \+; though matching no sandwiched spaces and replacing them with nothing doesn't do harm, it's imprecise (and may be a bit more inefficient).

To arrive at the correct pattern, we need to turn the AND to OR, by introducing a branch with \| (:help /\bar):

/\a\@<! \+\| \+\a\@!/
2
  • 1
    Thank you for the detailed explanation. What if some of the letters are accented characters like Š or é? What should I use instead of \a?
    – arty
    Commented Oct 31, 2019 at 12:55
  • 3
    That's unfortunately still a weak spot in Vim; all built-in classes and sets do not contain them; you have to include them yourself; see stackoverflow.com/questions/19385458/… Commented Oct 31, 2019 at 13:13
2

You can make use of \zs and \ze.

:s/\v^\s+|\s+$|[^[:alpha:][:space:]]\zs\s+|\s+\ze[^[:alpha:][:space:]]//g

:s/\v<pat1>|<pat2>|<pat3>|<pat4>//g --- delete all matches using "very magic" mode

^\s+ --- leading spaces

\s+$ --- trailing spaces

[^[:alpha:][:space:]]\zs\s+ --- matches anything except alpha or space followed by space(s), but selects space(s) only

\s+\ze[^[:alpha:][:space:]] --- matches space(s) followed by anything except alpha or space, but selects space(s) only

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.