Подсчитать количество предложений в тексте с помощью Python? [Дубликат]

Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

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

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

13
задан smci 9 September 2014 в 05:11
поделиться

9 ответов

(?<!\w\.\w.)(?<![A-Z][a-z]\.)(?<=\.|\?)\s

Попробуйте это. разделите свою строку this.You также можете проверить демо.

http://regex101.com/r/nG1gU7/27

17
ответ дан vks 17 August 2018 в 14:32
поделиться
  • 1
    Проблема заключается в том, что он не имеет дело с тремя периодами в конце предложения. Он берет последние два из трех и помещает их в начало следующего предложения. – user3590149 9 September 2014 в 04:07
  • 2
    Я добавил образец выше. – user3590149 9 September 2014 в 04:11
  • 3
    Спасибо, что это работает! – user3590149 9 September 2014 в 04:15
  • 4
    @ user3590149, когда вы разделите на него один ., будет потерян. Вы можете записать его позже для каждого предложения, и все готово. – vks 9 September 2014 в 04:15
  • 5
    если вы разделите в соответствии с точкой, точка исчезнет в конечном выходе. – Avinash Raj 9 September 2014 в 04:54

Наивный подход для правильных английских предложений, не начинающийся с неалфаза и не содержащий цитируемых частей речи:

import re
text = """\
Mr. Smith bought cheapsite.com for 1.5 million dollars, i.e. he paid a lot for it. Did he mind? Adam Jones Jr. thinks he didn't. In any case, this isn't true... Well, with a probability of .9 it isn't.
"""
EndPunctuation = re.compile(r'([\.\?\!]\s+)')
NonEndings = re.compile(r'(?:Mrs?|Jr|i\.e)\.\s*$')
parts = EndPunctuation.split(text)
sentence = []
for part in parts:
  if len(part) and len(sentence) and EndPunctuation.match(sentence[-1]) and not NonEndings.search(''.join(sentence)):
    print(''.join(sentence))
    sentence = []
  if len(part):
    sentence.append(part)
if len(sentence):
  print(''.join(sentence))

Ложное положительное расщепление может быть уменьшено путем расширения NonEndings немного. В других случаях потребуется дополнительный код. [1]

Вы никогда не достигнете совершенства при таком подходе. Но в зависимости от задачи он может просто работать «достаточно» ...

0
ответ дан Ali 17 August 2018 в 14:32
поделиться

Попробуйте разбить вход в соответствии с пробелами, а не точкой или ?, если вы сделаете это так, точка или ? не будут напечатаны в конечном результате.

>>> import re
>>> s = """Mr. Smith bought cheapsite.com for 1.5 million dollars, i.e. he paid a lot for it. Did he mind? Adam Jones Jr. thinks he didn't. In any case, this isn't true... Well, with a probability of .9 it isn't."""
>>> m = re.split(r'(?<=[^A-Z].[.?]) +(?=[A-Z])', s)
>>> for i in m:
...     print i
... 
Mr. Smith bought cheapsite.com for 1.5 million dollars, i.e. he paid a lot for it.
Did he mind?
Adam Jones Jr. thinks he didn't.
In any case, this isn't true...
Well, with a probability of .9 it isn't.
4
ответ дан Avinash Raj 17 August 2018 в 14:32
поделиться
  • 1
    Хорошо работает на хорошо отформатированном тексте (т. Е. Все предложения должны начинаться с прописной буквы) – Iulius Curt 15 March 2016 в 14:36

Я написал это с учетом комментариев smci выше. Это подход среднего класса, который не требует внешних библиотек и не использует регулярное выражение. Это позволяет вам предоставлять список сокращений и счетов для предложений, заканчивающихся терминаторами в оболочках, таких как период и цитата: [. ",? '..]].

abbreviations = {'dr.': 'doctor', 'mr.': 'mister', 'bro.': 'brother', 'bro': 'brother', 'mrs.': 'mistress', 'ms.': 'miss', 'jr.': 'junior', 'sr.': 'senior', 'i.e.': 'for example', 'e.g.': 'for example', 'vs.': 'versus'}
terminators = ['.', '!', '?']
wrappers = ['"', "'", ')', ']', '}']


def find_sentences(paragraph):
   end = True
   sentences = []
   while end > -1:
       end = find_sentence_end(paragraph)
       if end > -1:
           sentences.append(paragraph[end:].strip())
           paragraph = paragraph[:end]
   sentences.append(paragraph)
   sentences.reverse()
   return sentences


def find_sentence_end(paragraph):
    [possible_endings, contraction_locations] = [[], []]
    contractions = abbreviations.keys()
    sentence_terminators = terminators + [terminator + wrapper for wrapper in wrappers for terminator in terminators]
    for sentence_terminator in sentence_terminators:
        t_indices = list(find_all(paragraph, sentence_terminator))
        possible_endings.extend(([] if not len(t_indices) else [[i, len(sentence_terminator)] for i in t_indices]))
    for contraction in contractions:
        c_indices = list(find_all(paragraph, contraction))
        contraction_locations.extend(([] if not len(c_indices) else [i + len(contraction) for i in c_indices]))
    possible_endings = [pe for pe in possible_endings if pe[0] + pe[1] not in contraction_locations]
    if len(paragraph) in [pe[0] + pe[1] for pe in possible_endings]:
        max_end_start = max([pe[0] for pe in possible_endings])
        possible_endings = [pe for pe in possible_endings if pe[0] != max_end_start]
    possible_endings = [pe[0] + pe[1] for pe in possible_endings if sum(pe) > len(paragraph) or (sum(pe) < len(paragraph) and paragraph[sum(pe)] == ' ')]
    end = (-1 if not len(possible_endings) else max(possible_endings))
    return end


def find_all(a_str, sub):
    start = 0
    while True:
        start = a_str.find(sub, start)
        if start == -1:
            return
        yield start
        start += len(sub)

Я использовал Karl's find_all из этой записи: Найти все вхождения подстроки в Python

0
ответ дан Community 17 August 2018 в 14:32
поделиться

Если вы хотите разбить предложения на 3 периода (не уверен, что это то, что вы хотите), вы можете использовать это регулярное выражение:

import re

text = """\
Mr. Smith bought cheapsite.com for 1.5 million dollars, i.e. he paid a lot for it. Did he mind? Adam Jones Jr. thinks he didn't. In any case, this isn't true... Well, with a probability of .9 it isn't.
"""
sentences = re.split(r'\.{3}', text)

for stuff in sentences:
     print(stuff)    
-1
ответ дан Jose Varez 17 August 2018 в 14:32
поделиться
sent = re.split('(?<!\w\.\w.)(?<![A-Z][a-z]\.)(?<=\.|\?)(\s|[A-Z].*)',text)
for s in sent:
    print s

Здесь используется регулярное выражение: (?<!\w\.\w.)(?<![A-Z][a-z]\.)(?<=\.|\?)(\s|[A-Z].*)

Первый блок: (?<!\w\.\w.): этот шаблон ищет в цикле отрицательной обратной связи (?<!) для всех слов (\w), за которым следует полный запуск (\.), за которым следуют другие слова (\.)

Второй блок: (?<![A-Z][a-z]\.): этот шаблон выполняет поиск в цикле отрицательной обратной связи для чего-либо, начиная с букв верхнего регистра ([A-Z]), а затем строчных алфавитов ([a-z]) пока не будет найдена точка (\.).

Третий блок: (?<=\.|\?): этот шаблон ищет в контуре обратной связи точки (\.) ИЛИ вопросительный знак (\?)

Четвертый блок : (\s|[A-Z].*): эта модель выполняет поиск после точки или вопросительного знака из третьего блока. Он ищет пустое пространство (\s) ИЛИ любую последовательность символов, начиная с алфавита верхнего регистра ([A-Z].*). Этот блок очень важен для разделения, если вход такой как

Hello world.Hi Я здесь сегодня.

i.e. если после точки есть пробел или пробел.

2
ответ дан Mehul Gupta 17 August 2018 в 14:32
поделиться

Я не очень хорош в регулярных выражениях, но более простая версия «грубая сила» на самом деле выше

sentence = re.compile("([\'\"][A-Z]|([A-Z][a-z]*\. )|[A-Z])(([a-z]*\.[a-z]*\.)|([A-Za-z0-9]*\.[A-Za-z0-9])|([A-Z][a-z]*\. [A-Za-z]*)|[^\.?]|[A-Za-z])*[\.?]")

, что означает, что допустимые единицы запуска: «[AZ] или« [AZ ] Обратите внимание, что большинство регулярных выражений жадные, поэтому порядок очень важен, когда мы делаем (или). Вот почему я написал, то есть регулярное выражение, а затем пришло таких форм, как Inc.

0
ответ дан Priyank Pathak 17 August 2018 в 14:32
поделиться

Хорошо, так что предложения-токенизаторы - это то, на что я смотрел в деталях, используя регулярные выражения, nltk, CoreNLP. Вы в конечном итоге пишете свои собственные, и это зависит от приложения. Этот материал сложный и ценный, и люди не просто отдают свой код токенизатора. (В конечном счете, токенизация не является детерминированной процедурой, она вероятностна и также очень сильно зависит от вашего корпуса или домена, например, сообщения в социальных сетях против обзоров Yelp vs. ...)

В общем, вы не можете полагайтесь на одно непогрешимое регулярное выражение Great White, вам нужно написать функцию, которая использует несколько регулярных выражений (как положительных, так и отрицательных); также словарь аббревиатур и некоторый базовый язык, который знает, что, например, «Я», «США», «FCC», «TARP» капитализируются на английском языке.

Чтобы проиллюстрировать, насколько легко это может серьезно осложниться, попробуем написать вам эту функциональную спецификацию для детерминированного токенизатора просто решить, будет ли один или несколько периодов ('.' / '...') обозначать конец предложения или что-то еще:

function isEndOfSentence(leftContext, rightContext)

  1. Возврат Ложно для десятичных знаков внутри чисел или валюты, например 1.23, $ 1.23: «Это просто мои $ .02» . Рассмотрим также ссылки на разделы, такие как 1.2.3 или европейские форматы даты, например 09.07.2014
  2. Возврат False (и не tokenize на отдельные буквы) для известных сокращений, например «Запасы США падают»; для этого требуется словарь известных сокращений. Все, что за пределами этого словаря вы ошибетесь.
  3. Эллипсы «...» в конце предложений являются терминальными, но в середине предложений нет. Это не так просто, как вы могли бы подумать: вам нужно взглянуть на левый контекст и правильный контекст, в частности, заглавный RHS и снова рассмотреть заглавные слова типа «я» и аббревиатуры. Вот пример доказательства двусмысленности, который: Она попросила меня остаться ... Я ушел через час. (Было ли это одно предложение или два? Невозможно определить)
  4. Вы также можете хотите написать несколько шаблонов, чтобы обнаруживать и отклонять разные варианты прерывания, отличные от предложения: символика, искусство ASCII, эллипсы на расстоянии. , , и другие вещи esp. Twitter. (Сделать эту адаптивность еще сложнее). Как узнать, является ли @midnight пользователем Twitter, показателем в Comedy Central или просто пунктуацией нежелательной / нежелательной / опечатки? Серьезно нетривиально.
  5. После того, как вы справитесь со всеми этими отрицательными случаями, вы можете произвольно сказать, что любой изолированный период, за которым следуют пробелы, скорее всего, будет окончанием предложения. (В конечном счете, если вы действительно хотите приобрести дополнительную точность, вы в конечном итоге пишете свой собственный вероятностный фреймворк предложения, который использует веса и обучает его конкретному корпусу (например, юридические тексты, широковещательные СМИ, StackOverflow, Twitter, комментарии к форуму и т. Д.), ) Затем вам нужно вручную просмотреть образцы и ошибки обучения. См. Книгу Маннинга и Джурафского или курс Курсера [a]. В конечном итоге вы получаете столько же корректности, сколько готовы заплатить.
  6. . Все вышеизложенное четко относится к англоязычным / аббревиатурам, форматам US number / time / date. Если вы хотите сделать это независимым от страны и языка, это более важное предложение, вам понадобятся корпорация, люди, говорящие на родном языке, для маркировки и QA, и т. Д.
  7. Все вышеизложенное остается только ASCII. Разрешить ввод Unicode, и все становится еще сложнее (и набор тренировок обязательно должен быть либо намного большим, либо намного реже)

В простом (детерминированном) случае function isEndOfSentence(leftContext, rightContext) возвращает boolean, но в более общем смысле это вероятностно: он возвращает float (уровень уверенности, что этот конкретный «.» - конец предложения).

Ссылки: [a] Видео Coursera: «Обработка основного текста 2-5 - Сегментация предложений - Стэнфордская НЛП - Профессор Дэн Юрафски и Крис Маннинг»

23
ответ дан smci 17 August 2018 в 14:32
поделиться
  • 1
    Это последнее видео, которое вы связали, очень хорошо, спасибо. – bootsmaat 8 July 2016 в 15:32
  • 2
    @bootsmaat: видео Джурафски хорошее, но оно охватывает только детерминированные, а не вероятностные, символизирующие. Реальный подход должен быть вероятностным. – smci 19 December 2017 в 00:05

Попробуйте следующее:

(?<!\b(?:[A-Z][a-z]|\d|[i.e]))\.(?!\b(?:com|\d+)\b)
0
ответ дан walid toumi 17 August 2018 в 14:32
поделиться
  • 1
    это работает с командой split. Я получил недействительный синтаксис в первый раз? – user3590149 9 September 2014 в 03:48
  • 2
    Используйте модуль regex вместо модуля re. – walid toumi 9 September 2014 в 03:55
  • 3
    Проблема заключается в том, что он не имеет дело с тремя периодами в конце предложения. Он берет последние два из трех и помещает их в начало следующего предложения. – user3590149 9 September 2014 в 04:07
Другие вопросы по тегам:

Похожие вопросы: