Поскольку для вас работает наивный подход, я отправляю ответ. Однако обратите внимание, что определение конца предложения является очень сложной задачей для регулярного выражения, и хотя это возможно в какой-то мере, для этого следует использовать пакет NLP.
Сказав это, я предложил использовать
'~(?<!\be\.g)\.(?=\s+\p{Lu})~ui'
Регулярного выражение соответствует любой точке (\.
), не предшествуют с целым словом e.g
(см отрицательных назад '(?<!\be\.g)
), но следует с 1 или больше пробелов (\s+
), за которым следует 1 заглавная буква Юникода \p{Lu}
.
См regex demo
Дело нечувствителен i
модификатор не влияет на какие \p{Lu}
матчей.
Редактор ~u
необходим, так как вы работаете с текстами Unicode (например, на русском).
Чтобы получить индекс первого вхождения, используйте функцию preg_match
с флагом PREG_OFFSET_CAPTURE
. Вот немного упрощена регулярное выражение вы указали в комментариях:
preg_match('~(?<!т\.н)(?<!т\.к)(?<!e\.g)\.(?=\s+\p{L})~iu', $text, $match, PREG_OFFSET_CAPTURE);
Посмотреть lookaheads выполняются один за другим, и в том же месте в строке, таким образом, вы не должны дополнительно сгруппировать их внутри положительный предпросмотр , См. regex demo.
IDEONE demo:
$re = '~(?<!т\.н)(?<!т\.к)(?<!e\.g)\.(?=\s+\p{L})~iu';
$str = "cats, e.g. Barsik, are funny. And it is true. So,";
preg_match($re, $str, $match, PREG_OFFSET_CAPTURE);
echo $match[0][1];
Ваше название вводит в заблуждение, как вам нужно, чтобы соответствовать до первой полной остановки, что указывает на конец предложения.Вот наивный подход: '' ~ (?
@Wiktor Stribiżew, спасибо – mnv
Есть и другие сокращения, это не будет работать во всех случаях. –