Можно разделить стринг на слова в массив, а потом пересобрать из него стринг, не используя слова короче 3х символов. А регуляркой такое возможно?
Пример в начальном посте видимо не срабатывает на 1ом и последнем символах. Если сделать
$str=preg_replace("/(^|\s)(\S{1,3})(\s|$)/"," ",$str);
то не срабатывает на среднем.