Question

I'm using vim (version 7.3).

On the following line

1xAxBx4

where A and B can be any alphanumerical character, I want to replace xBx4 with foo. I tried the following substitution command

:s/x.\{-}x4/foo/

and get 1foo instead of what I expected (1xAfoo). I can get 1xAfoo if I use this substitution command

:s/x[^A]x4/foo/

but this is too specific and won't be helpful if I want to replace on multiple lines, as "A" could be a different character on each line.

Why the unexpected behavior with \.{-}? Or is this exactly what one would expect, but I'm just misunderstanding the syntax?

Was it helpful?

Solution

Though you've correctly used the non-greedy \{-} quantifier, because there's no consumption before, it still will start matching at the first x, and then match as few as possible. Because that works, there's no backtracking.

Now, you need to add a greedy match before your expression, yet do not consume those characters. This can be achieved with \zs to let the match only start afterwards:

:s/.*\zsx.\{-}x4/foo/

OTHER TIPS

this is not the use case for "non-greedy".

x.\{-}x4 will make sense for example you want to replace:

xAAAx4BBBx4CCCx4 -> ######BBBx4CCCx4

without the usage of \{-} the result would be ######

if it is known that only one single character between x and x4, you just use x.x4 or if you want to avoid space to be selected, use x\Sx4

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top