tu dois faire un var_dump de $chaineSansCaractere
avant $chaineSansCaractere = preg_replace($res, $subst, $chaineAvecCaractere);
pour savoir sur quoi travail le replace de '/\]\&+\[/' par ' ' .
perso moi j'aurais mis $subst = chr(32); comme ça tu as la certitude que c'est 1 espace; le jour ou un gamin en stage joue avec ton script
et sans le savoir il ajoute un autre espace tu fera pas la différence entre ' ' et ' ' visuellement ça te sera compliqué
mais certain utilise aussi "\x32" à la place de chr(32) chacun son style.
bref je pense que le pre_replace met un espace devant.
avec le var_dump tu vas pouvoir avoir la chaine sur quoi travail le preg_replace et
avec un outils magique :
https://regex101.com/
tu pourra tester ta chaine et voir le comportement de '/\]\&+\[/'
copie ici la chaine obtenu par le var_dump de $chaineAvecCaractere
avant : $chaineSansCaractere = preg_replace($res, $subst, $chaineAvecCaractere);