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:

<span class="h">magic   nomagic   action    </span>
  <a class="d" href="https://vimhelp.org/change.txt.html#%26">&</a>       \&      replaced with the whole matched <a class="d" href="https://vimhelp.org/pattern.txt.html#pattern">pattern</a><span id="s%2F%5C%26" class="t"></span>
 \&        <a class="d" href="https://vimhelp.org/change.txt.html#%26">&</a>      replaced with <a class="d" href="https://vimhelp.org/change.txt.html#%26">&</a>

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):

<strong>&lt;foo&gt;</strong>lt;bar<strong>&lt;foo&gt;</strong>gt;

Getting it working…

Is simple as adding that escape - so adding the escapes

:s/&lt;foo&gt;/<strong>\</strong>&lt;bar\&gt;

The result is now as desired and expected:

&lt;bar&gt;