rnso
rnso

Reputation: 24535

Vim - removing leading and trailing spaces in a function

I am trying to remove leading and trailing spaces in a function but it does not work:

function Trim(s)
    echo ">>>".a:s."<<<"
    let ss = substitute(a:s, '\v^\s*([^\s]+)\s*$', '\1', '') 
    echo ">>>".ss."<<<"
endfunction

The regex \s*([^\s]+)\s* works ok on https://regex101.com/

Replacing * with + does not make any difference.

Testing:

: call Trim("   testing    ")

Output:

>>>   testing    <<<
>>>   testing    <<<

Also it seems to matter if I use double quotes versus single quotes in substitute function.

Where are the problems and how can they be solved? Thanks.

Upvotes: 0

Views: 1739

Answers (3)

Luc Hermitte
Luc Hermitte

Reputation: 32936

As romainl explained, [^\s] means neither \ nor s. The contrary of \s (i.e. anything but a space or a tab) would be \S.

Otherwise, here is another solution: in lh-vim-lib I've defined the following

function! lh#string#trim(string) abort
  return matchstr(a:string, '^\v\_s*\zs.{-}\ze\_s*$')
endfunction

Regarding the difference(s) between the various kinds of quote characters, see this Q/A on vi.SE: https://vi.stackexchange.com/questions/9706/what-is-the-difference-between-single-and-double-quoted-strings

Upvotes: 2

romainl
romainl

Reputation: 196546

Your issue is caused by your collection.

You should use [^ ] instead of [^\s]:

function! Trim(s)
    echo ">>>".a:s."<<<"
    let ss = substitute(a:s, '\v^\s*([^ ]+)\s*$', '\1', '') 
    echo ">>>".ss."<<<"
endfunction

This is because collections work on individual characters and \s is not an individual character; it's seen as \ followed by s, which doesn't resolve to anything because s is not a special character that needs escaping.

If you want your collection to include both spaces and tabs, use this:

[^ \t]
[ \t]

where \t represents a tab.

Upvotes: 3

Lieven Keersmaekers
Lieven Keersmaekers

Reputation: 58441

You are including what needs to be retained in your search/replace. Much easier is to just look for what needs te be removed and substitute that

:%s/\v(^\s+|\s+$)//g

Breakdown

%s             Start a global search/replace
\v             Use Very Magic 
(^\s+          search for leading spaces
|              or
\s+$)          search for trailing spaces
//g            remove all search results from entire line

Upvotes: 1

Related Questions