Как уже упоминалось в моем комментарии выше, если вы не можете определить фиксированный набор крайних случаев, это может быть невозможно без ложных срабатываний или ложных отрицаний. Опять же, без контекста вы не можете определить guish между аббревиатурами, такими как "-Sgt. Smith", и концами предложений, таких как "Sergeant часто сокращается как Sgt. Это делает его короче.".
Однако, если вы можете определить фиксированный набор крайних случаев, это, вероятно, будет проще и намного более читабельно сделать это в несколько шагов.
1. Определите ваши крайние случаи
Например, вы можете назначить guish «У меня будет № 3» и «Нет. Я ваш отец», проверив следующий номер. Таким образом, вы бы идентифицировали этот крайний случай с помощью регулярного выражения, подобного этому: No. \d
. (Опять же, контекст имеет значение. Такие предложения, как «Достаточно ли 200? Нет, недостаточно 200.» Все равно дадут вам ложный положительный результат)
2. Маскируйте ваши крайние случаи
Для каждого краевого случая маскируйте строку соответствующей строкой, которая на 100% не будет частью исходного текста. Например, "Нет" => "====== НОМЕР ======"
3. Запустите ваш алгоритм
Теперь, когда вы избавились от нежелательных знаков препинания, вы можете выполнить более простое регулярное выражение, подобное этому, чтобы определить истинные положительные моменты: [\.\!\?]\s
4. Снимите маски с краев
Превратите "====== NUMBER ======" в "Нет"