あ、しまった。なんか書き込み時に&が勝手に変換されちゃってる。
仕方ないので半角&を全角&にして書き込んでみます。

$text= htmlspecialchars('ハートだよ♥');//文字列全体をエスケープ。&は実際には半角
$regex = "^&{1}[0-9]{3,6};$";//&は実際には半角
preg_replace("/".$regex."/", "&\1", $text);//実体参照文字だけをアンエスケープ