Расширенное решение регулярных выражений
Если вы заботитесь об обработке: Mr.
и Mrs.
и т. Д. Сокращений, то следующее единственное решение регулярных выражений работает довольно хорошо:
<?php // test.php Rev:20160820_1800
$split_sentences = '%(?#!php/i split_sentences Rev:20160820_1800)
# Split sentences on whitespace between them.
# See: http://stackoverflow.com/a/5844564/433790
(?<= # Sentence split location preceded by
[.!?] # either an end of sentence punct,
| [.!?][\'"] # or end of sentence punct and quote.
) # End positive lookbehind.
(?<! # But don\'t split after these:
Mr\. # Either "Mr."
| Mrs\. # Or "Mrs."
| Ms\. # Or "Ms."
| Jr\. # Or "Jr."
| Dr\. # Or "Dr."
| Prof\. # Or "Prof."
| Sr\. # Or "Sr."
| T\.V\.A\. # Or "T.V.A."
# Or... (you get the idea).
) # End negative lookbehind.
\s+ # Split on whitespace between sentences,
(?=\S) # (but not at end of string).
%xi'; // End $split_sentences.
$text = 'This is sentence one. Sentence two! Sentence thr'.
'ee? Sentence "four". Sentence "five"! Sentence "'.
'six"? Sentence "seven." Sentence \'eight!\' Dr. '.
'Jones said: "Mrs. Smith you have a lovely daught'.
'er!" The T.V.A. is a big project! '; // Note ws at end.
$sentences = preg_split($split_sentences, $text, -1, PREG_SPLIT_NO_EMPTY);
for ($i = 0; $i < count($sentences); ++$i) {
printf("Sentence[%d] = [%s]\n", $i + 1, $sentences[$i]);
}
?>
Обратите внимание, что вы можете легко добавлять или убирать сокращения из выражения. Учитывая следующий тестовый параграф:
Это первое предложение. Приговор два! Приговор три? Приговор "четыре". Приговор "пять"! Приговор "шесть"? Приговор "семь". Приговор "восемь!" Доктор Джонс сказал: «Миссис Смит, у вас прекрасная дочь!» Т.В.А. большой проект!
Вот вывод из скрипта:
Sentence[1] = [This is sentence one.]
Sentence[2] = [Sentence two!]
Sentence[3] = [Sentence three?]
Sentence[4] = [Sentence "four".]
Sentence[5] = [Sentence "five"!]
Sentence[6] = [Sentence "six"?]
Sentence[7] = [Sentence "seven."]
Sentence[8] = [Sentence 'eight!']
Sentence[9] = [Dr. Jones said: "Mrs. Smith you have a lovely daughter!"]
Sentence[10] = [The T.V.A. is a big project!]
необходимое решение регулярных выражений
Автор вопроса отметил, что приведенное выше решение "пропускает множество вариантов" и не является достаточно универсальным. Я не уверен, что это значит, но суть вышеприведенного выражения настолько проста и понятна, насколько это возможно. Вот оно:
$re = '/(?<=[.!?]|[.!?][\'"])\s+(?=\S)/';
$sentences = preg_split($re, $text, -1, PREG_SPLIT_NO_EMPTY);
Обратите внимание, что оба решения правильно идентифицируют предложения, заканчивающиеся кавычкой после конечной пунктуации. Если вас не интересуют совпадающие предложения, заканчивающиеся кавычкой, регулярное выражение можно упростить до: /(?<=[.!?])\s+(?=\S)/
.
Редактировать: 20130820_1000 Добавлено T.V.A.
(еще одно пунктуированное слово, которое следует игнорировать) для регулярного выражения и проверки строки. (чтобы ответить на вопрос с комментариями PapyRef)
Редактировать: 20130820_1800 Приведены в порядок и переименованы регулярное выражение и добавлен Шебанг. Также исправлены регулярные выражения для предотвращения разделения текста на конечные пробелы.