Try changing:
$str = preg_replace('/[^a-zA-Z0-9]/i', ' ', $str);
to:
$str = preg_replace('/[^a-z0-9\s]/i', '', $str);
This will not put spaces where you don't want them but allow the ones that are already there to stay (for now). Then you won't have spaces in the middle of words. (I also took out the A-Z
from your regex since it is not necessary since the string is already lowercase and you are also using the i
modifier which makes it case insensitive anyway).