Use a variable as the replacement safely
In Bash 5.2 an ampersand in the replacement of ${v//old/new} stands for the matched text. Quote the replacement or turn off patsub_replacement.
A substitution that worked in Bash 5.1 now prints the match where a literal ampersand should be, and this is how to get the old behaviour back.
v="cat and cat"
r='[&]'
echo "${v//cat/$r}"
echo "${v//cat/"$r"}"
shopt -u patsub_replacement
echo "${v//cat/$r}"[cat] and [cat]
[&] and [&]
[&] and [&]Bash 5.2 added the patsub_replacement option, which is on by default and makes an unquoted ampersand in the replacement string mean "the text that matched", the way it does in sed. The option is listed in the shopt section of the manual. Quoting the expansion inside the replacement keeps the ampersand literal, and shopt -u patsub_replacement removes the feature for the rest of the script.
Bash 5.1 and earlier treat the ampersand as an ordinary character, so a script that relies on the new meaning does not run there. Quote replacements that come from user input, or a stray ampersand rewrites the output.