Регулярное совпадение. (периоды, обозначающие конец приговоров), но не г-н (как у г-на Хопкинса)

Я пытаюсь разобрать текстовый файл в предложениях, заканчивающихся в периоды, но такие имена, как г-н Хопкинс, бросают ложные тревоги на соответствие периодам.

То, что regex идентифицирует "." но не "Мистер".

Для бонуса я тоже использую! чтобы найти конец предложений, поэтому мое текущее Regex есть /(!/./, и мне бы понравился ответ, который тоже включает мой.

Ответ 1

Используйте негативный внешний вид.

(?<!Mr|Mrs|Dr|Ms)\.

Это будет соответствовать периоду, только если он не появится после Mr, Mrs, Dr или Ms

<?
   $str = "This is Mr. Someone and Mrs. Somebody. They are here to meet Dr. SomeoneElse.";
   $str = preg_replace("/(?<!Mr|Mrs|Dr|Ms)\\./", "\n", $str);
   echo($str);
?>
//outputs:
This is Mr. Someone and Mrs. Somebody
 They are here to meet Dr. SomeoneElse

Ответ 2

Это невозможно сделать с помощью любого простого механизма. Это безнадежно двусмысленно. Предложения могут заканчиваться аббревиатурами, и в этих случаях они не записываются с двумя периодами.

См. Unicode TR29. Также см. Библиотеку с открытым исходным кодом ICU, которая включает базовую реализацию.

Ответ 3

В ваших предложениях всегда следуют два пробела? Если это так, вы можете просто проверить это...

/\.\s{2}/

и включение символа препинания другого конца: /[\.\!\?]\s{2}/

Вы также можете проверить другие вещи, которые могут быть индикаторами конца предложения, например, если следующее слово заглавное, за ним следует возврат каретки и т.д. Но в лучшем случае вы просто сможете сделать как указывалось выше, период слишком неоднозначен.