Ich würde ungefähr so ansetzen und dann ausprobieren, ob es auch das macht, was ich möchte (wobei ich persönlich eher die Mbstring-Variante benutzen würde statt preg_replace):
CODE $string = preg_replace('/(\W)[^A-Z]+(\W)/m', '\1\2', $string);
oder nur auf den Anfangsbuchstaben bezogen:
CODE $string = preg_replace('/(\W)[^A-Z]\w*(\W)/m', '\1\2', $string);
\W → any "non-word" character
PS: Alain: Das sieht irgendwie übel aus.