Еще лучше было бы отрицательное прогнозное утверждение для проверки, за которым не следует
/&(?!amp;)/
Хотя это изменит любые амперсанды, используемые для других сущностей. Если у вас есть вероятность, что у вас есть другие, то как насчет чего-то вроде
/&(?!#?[a-zA-Z0-9]+;)/
Это будет искать амперсанд, но при этом утверждается, что за ним НЕ следует необязательный хэш-символ (для числовых объектов), серия буквенно-цифровых символов и точка с запятой, которая должна охватывать именованных и числовых объектов , таких как "e;
или ª
Тестовый код
$text="It’s 30 ° outside & very hot. T-shirt & shorts needed!";
$text=preg_replace('/&(?!#?[a-z0-9]+;)/', '&', $text);
echo "$text\n";
Который выдаст
It’s 30 ° outside & very hot. T-shirt & shorts needed!
, который легче читать как "На улице 30 °, очень жарко. Требуются футболка и шорты!"
Альтернатива для PHP 5.2.3 +
Как указывает Ионут Дж. Стэн ниже, из PHP 5.2.3 вы можете использовать htmlspecialchars с четвертым параметром false для предотвращения двойного кодирования, например
$text=htmlspecialchars($text,ENT_COMPAT,"UTF-8",false);