It's not totally simple, considering there are cases where periods appear in the middle of a sentence. Unless you start parsing the entire English language, though, you'll have to deal with occasional foul-ups.
$string =~ s/((?:^\s*|[!?.]+\s+)[^a-zA-Z0-9]*)([a-z])/$1\u$2/g;