Regex, чтобы найти все предложения текста? - PullRequest
3 голосов
/ 23 августа 2010

Я пытался научить себя регулярным выражениям в python, и я решил распечатать все предложения текста.Последние 3 часа я возился с регулярными выражениями безрезультатно.

Я просто попробовал следующее, но ничего не смог сделать.

p = open('anan.txt')
process = p.read()
regexMatch = re.findall('^[A-Z].+\s+[.!?]$',process,re.I)
print regexMatch
p.close()

Мой входной файл выглядит так:

OMG is this a question ! Is this a sentence ? My.
name is.

Это не печатает никаких выходных данных.Но когда я удаляю «My. Name is.», Он печатает OMG, это вопрос и является ли это предложение вместе, как если бы он читал только первую строку.

Какое наилучшее решение для регулярных выражений можно найтивсе предложения в текстовом файле - независимо от того, переносит ли предложение новую строку или около того - а также читает весь текст?Спасибо.

Ответы [ 7 ]

8 голосов
/ 23 августа 2010

Примерно так работает:

## pattern: Upercase, then anything that is not in (.!?), then one of them
>>> pat = re.compile(r'([A-Z][^\.!?]*[\.!?])', re.M)
>>> pat.findall('OMG is this a question ! Is this a sentence ? My. name is.')
['OMG is this a question !', 'Is this a sentence ?', 'My.']

Обратите внимание, что name is. отсутствует в результате, потому что оно не начинается с заглавной буквы.

Ваша проблема связана с использованием ^$ якорей, они работают со всем текстом.

5 голосов
/ 23 августа 2010

В вашем регулярном выражении есть две проблемы:

  1. Ваше выражение привязано к ^ и $, которые являются "началом строки" и "концом"линии "якоря, соответственно.Это означает, что ваш шаблон соответствует всей строке вашего текста.
  2. Вы ищете \s+ перед вашим знаком пунктуации, который указывает один или несколько пробельных символов.Если перед пунктуацией у вас нет пробелов, выражение не будет совпадать.
3 голосов
/ 23 августа 2010

Отредактировано: теперь оно будет работать и с многострочными предложениями.

>>> t = "OMG is this a question ! Is this a sentence ? My\n name is."
>>> re.findall("[A-Z].*?[\.!?]", t, re.MULTILINE | re.DOTALL )
['OMG is this a question !', 'Is this a sentence ?', 'My\n name is.']

Осталось объяснить только одну вещь - re.DOTALL заставляет . соответствовать символу новой строки, как описано здесь

1 голос
/ 07 марта 2018

Спасибо, Чжи и Йохен Ритцель.

sentence=re.compile("[A-Z].*?[\.!?] ", re.MULTILINE | re.DOTALL )

Я думаю, что это лучше, просто добавьте пробел в конце.

 SampleReport='I image from 08/25 through 12. The patient image 1.2, 23, 34, 45 and 64 from serise 34. image look good to have a tumor in this area.  It has been resected during the interval between scans.  The'

, если использовать

pat = re.compile(r'([A-Z][^\.!?]*[\.!?])', re.M)
pat.findall(SampleReport)

Результат будет:

['I image from 08/25 through 12.',
'The patient image 1.',
 'It has been resected during the interval between scans.']

Ошибка в том, что он не может обрабатывать цифры, такие как 1,2.Но этот работает отлично.

sentence.findall(SampleReport)

Результат

['I image from 08/25 through 12. ',
'The patient image 1.2, 23, 34, 45 and 64 from serise 34. ',
 'It has been resected during the interval between scans. ']
1 голос
/ 23 августа 2010

Я попробовал на Notepad ++, и я получил это:

.*$

И активировать опцию мультилинии:

re.MULTILINE

Приветствия

0 голосов
/ 23 августа 2010

Вы можете попробовать:

p = open('a')
process = p.read()
print process
regexMatch = re.findall('[^.!?]+[.!?]',process)
print regexMatch
p.close()

Здесь используется регулярное выражение [^.!?]+[.!?], которое пытается сопоставить один или несколько разделителей без предложений, за которыми следует разделитель предложений.

0 голосов
/ 23 августа 2010

Попробуйте наоборот: разделите текст по границам предложений.

lines = re.split(r'\s*[!?.]\s*', text)

Если это не сработает, добавьте \ перед ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...