Vim sub-replace-special – ampersands in substitute search/replace

Curious…

While editing in vim you want to search and replace including a sub-string with an ampersand (&) – this doesn’t have an special regular expression meaning but given the input:

<foo>

And the search/replace (changing “foo” to “bar”):

:s/<foo>/<bar>

The result is:

<foo>lt;bar<foo>gt;

That looks… unexpected? Well, at least, undesired!

What’s going on?

Reading up on vim’s substitute command, we find a section on sub-replace-special where we find:

magic   nomagic   action    
  &       \&      replaced with the whole matched pattern
 \&        &      replaced with &

Where magic is enabled by default – so what’s happening is this:

On the right-hand side of the substitute (ie the output side) a non-escaped ampersand will be replace by the whole matched pattern, so the output suddenly makes sense (even though it’s still unwanted). Importantly note the ampersand on the left-hand-side is ok un-escaped as you would usually expect for a regular expression.

In this particular case it looks like a complete mess because of having multiple ampersands on the right-hand-side, but it now makes sense (where I’ve shown the whole matched pattern in the output in bold for the two ampersands in the output):

<foo>lt;bar<foo>gt;

Getting it working…

Is simple as adding that escape – so adding the escapes

:s/<foo>/\<bar\>

The result is now as desired and expected:

<bar>

Leave a Reply

Your email address will not be published. Required fields are marked *