Search code examples
vimnon-greedy

vim non-greedy unexpected behavior


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?


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/