> I have used vim for a while, and though no expert I am fairly
> comfortable with the common commands. Recently I ran into a situation
> where I just couldn't find a way to do a search and replace. I was
> hoping some of you experts could help me out.
> 
> Starting text:
> nameTable[pattern with spaces0] = ("pattern with spaces0", 12345)
> nameTable[pattern with spaces1] = ("pattern with spaces1", 67890)
> nameTable[pattern with spaces2] = ("pattern with spaces2", 243)
> nameTable[pattern with spaces3] = ("pattern with spaces3", 421)
> nameTable[pattern with spaces4] = ("pattern with spaces4", 3455)
> nameTable[pattern with spaces5] = ("pattern with spaces5", 2222)
> 
> Desired Text:
> nameTable[patternwithspaces0] = ("pattern with spaces0", 12345)
> nameTable[patternwithspaces1] = ("pattern with spaces1", 67890)
> nameTable[patternwithspaces2] = ("pattern with spaces2", 243)
> nameTable[patternwithspaces3] = ("pattern with spaces3", 421)
> nameTable[patternwithspaces4] = ("pattern with spaces4", 3455)
> nameTable[patternwithspaces5] = ("pattern with spaces5", 2222)
> 
> 
> Notice that the only difference is that the spaces are removed from
> the pattern in between the square brackets. I think I want to use \zs
> and \ze, but I couldn't wrap my head around the syntax. Any help would
> be appreciated.

There are a number of ways to do this depending on the complexity
of your document.  For the case you describe, this could easily
just be done with

:%s/pattern with spaces/patternwithspaces

By omitting the "g" flag, it replaces only the first instance on
the line.

If, however, "pattern with spacesN" each represents a different
pattern, things get a little more complex.  Something like the
following might do the trick:

:%s/nameTable\[\zs[^]]*/\=substitute(submatch(0), '\s', '', 'g')


This, as you suggested, uses the \zs tag.  However, it also uses
the incredibly-useful "\=" for expression evaluation which you
can read more about at

        :help sub-replace-special

You could tighten that search pattern if you needed, so that it
became

  /nameTable\[\zs[^]]*\ze] = ("...


Or if you needed to make it really tight, you could do something
like (broken into multiple lines for clarity, but should be all
one line with no spaces in the joining)

:%s/
\(nameTable\[\)
\([^]]\+\)
\(] = ("\1", \d\+)\)
/\=
submatch(1).
substitute(submatch(2), '\s', '', 'g').
submatch(3)

This will only match lines where the pattern with spaces appears
in both places...the one you want to replace, and the 2nd half
that you don't want to change.

All sorts of crazy stuff.  That last one is the tightest to what
you describe, but you might be able to get away with one of the
lazier options above. :)

-tim


Reply via email to