Это, кажется, делает трюк:
(?<!\s)\p{P}(?!\s)(?!$)
То есть:
(?<!\s)
: отрицательный взгляд назад, утверждая, что мы не появляемся после пробела \p{P}
: Соответствующая пунктуация (это общая категория знаков препинания в Юникоде) (?!\s)
: отрицательный прогноз, утверждающий, что мы не появляемся перед пробелами (?!$)
: еще один негативный взгляд, утверждающий, что мы не появляемся до конца файла
Вы также можете сделать это без косвенных утверждений, и вместо этого использовать группу захвата, чтобы извлечь символ пунктуации:
(?:[^\s]|^)(\p{P})[^\s$]
Я добавил тест, соответствующий началу строки, чтобы сохранить то же поведение, что и в первом регулярном выражении, когда символ пунктуации появляется в качестве первого символа в строке.Ваш вопрос не определяет поведение здесь.