how to non-capturing search and replace in vim

Viewed 5000

I'm trying to learn how to use regex with vim, and I'm currently trying to do a search and replace. I have something like this:

aaaaaaa&sometext&...
aaaaaaaanothertext

(the as are actually whitespace at the beginning of the line, that I don't know how to print that here)

And I want to replace the first occurence of & with & &, and keep everyting else as is. I'm using \%(...\) for non-capturing patterns, as suggested here, but the a pattern is still captured. I'm using :%s/\%(^a*\)&/& &/gc, and I get:

aaaaaaaa& aaaaaaaa&sometext&...
aaaaaaaaanothertext

I don't get why. I've also tried the replace with groups, as in :%s/\%(^a*\)\(&\)/\1 \1/gc, but then I get:

& &sometext&...
aaaaaaaanothertext

So, it seems the group is indeed being ignored for the group handling (since the first group is on the search pattern is &), but is still captured on the search pattern.

So, long story short, which replace command do I have to use to go from:

aaaaaaa&sometext&...

to:

aaaaaaa& &sometext&...

?

3 Answers

Typically in search and replace, it's sufficient for the substitute to completely replace the search. In this case, your search will include things you don't want to replace.

Vim has helpful patterns to define the start and end of a match: \zs and \ze. You can place \zs anywhere in the search, vim will only match after the start. You can use both to say, find this specific line and only replace a part of it.

And the solution:

:%s:^[^&]*\zs&:& &:c

  • %s: Look at every line in the file
  • ^[^&]*: From the beginning of the line, there should be zero or more not &
  • \zs&: The match to replace is a single &
  • & &: Replace the match with two &
  • c: Perform each substitution interactively in-case I suck at regex
Related