\p{P} соответствует всем символам пунктуации Unicode (см. Unicode свойства символа). Если вы только хотите разрешить определенную пунктуацию, просто добавьте их в класс отрицательных символов. Например:
preg_replace("/[^a-zA-Z0-9\s.?!]/", "", $str);
Ответ 2
Вам нужно будет явно указать пунктуацию, так как для этого нет сокращений (например, \s является сокращением символов пробела).