Plutôt que d'utiliser le modificateur e qui est déprécié depuis PHP 5.5 puis enlevé dans la version 7 (et découragé dans les versions précédentes) pour des questions de sécurité, mieux vaut utiliser preg_replace_callback qui est fait pour ça.
La classe de caractère [[:upper:]], c'est bien, mais ça ne fera guère plus que [A-Z] si tu n'ajoutes pas le modificateur u (ce qui inclura les caractères accentués et les e dans l'a et e dans l'o à [[:upper:]]).
Je ferai donc ça:
$result = preg_replace_callback('~\b[[:upper:]]\K[[:upper:]]+\b~u', function ($m) { return mb_strtolower($m[0], 'UTF-8'); }, $chaine);
ou en utilisant la classe de caractères unicode \p{Lu}:
$result = preg_replace_callback('~\b\p{Lu}\K\p{Lu}+\b~u', function ($m) { return mb_strtolower($m[0], 'UTF-8'); }, $chaine);
De cette manière on traite les caractères accentués qui correspondent à un point unicode. Mais un même caractère accentué peut avoir plusieurs représentations en unicode. Par exemple le À, peut être codé par le point unicode U+00C0 (LATIN CAPITAL LETTER A WITH GRAVE), mais il peut aussi être codé par U+0041 (LATIN CAPITAL LETTER A) suivi de U+0300 (COMBINING GRAVE ACCENT). (Table Unicode.)
Pour traiter également les caractères accentués composés d'un point unicode pour la lettre suivi d'un caractère combinant (ou plusieurs), on peut utiliser:
$result = preg_replace_callback('~\b\p{Lu}\pM*+\K[\p{Lu}\pM]+\b~u', function ($m) { return mb_strtolower($m[0], 'UTF-8'); }, $chaine);
Partager