Как разделить текст на предложения в питоне
Перейти к содержимому

Как разделить текст на предложения в питоне

  • автор:

Как разделить строку на символы python

Есть несколько способов как этого добиться, я расскажу про самый простой. Это использование встроенной функции list() , для того, чтобы преобразовать строку в список, состоящий из символов.

>>> sentence = 'I Love Hexlet!' >>> list(sentence) ['I', ' ', 'L', 'o', 'v', 'e', ' ', 'H', 'e', 'x', 'l', 'e', 't', '!'] 

Как разбить текст на отдельные предложения? [дубликат]

Как разбить текст на отдельные предложения? Вариант со splitlines() не подходить, так как текст может быть записан в одну строку.

Отслеживать
задан 27 фев 2013 в 9:43
3,288 4 4 золотых знака 36 36 серебряных знаков 49 49 бронзовых знаков

3 ответа 3

Сортировка: Сброс на вариант по умолчанию

Выражение игнорирует
1980г.
100руб.
100р.
100коп.
100к.
и.т.д.
и.т.п.
а также совмещенные знаки препинания.
Код здесь
http://ideone.com/pNpffv

Отслеживать
ответ дан 27 фев 2013 в 17:46
17.9k 3 3 золотых знака 46 46 серебряных знаков 86 86 бронзовых знаков

@ReinRaus: мне кажется, лучше имплементировать такую семантику: после знака/ов препинания должен быть пробел, последующее слово должно быть с большой буквы. Год и цена могут вполне заканчивать предложение.

27 фев 2013 в 18:28

Э, так у нас же каждое новое предложение начинается с большой буквы? Почему бы не искать то место, где стоит точка и идет заглавная буква? Конечно, есть исключения, вроде имен, городов и т.п. — но это уже в целый проект выливается. Тьфу, дублирую @VladD ну да пофиг.

27 фев 2013 в 21:46
UPD Исправил вчерашние ошибки, оказывается проблема была не в плохом самочувствии, а в этой проблеме
28 фев 2013 в 7:54

Интересно, а вложенные предложения могут быть? Поясню, есть предложение, в нем начинается цитата (в кавычках. Или скобках, как здесь), а потом оно продолжается. Как такую фигню разбирать? По идее это вопрос на форум Русский Язык, но регистрироваться там (по поводу малозначащей для меня проблемы) неохота.

28 фев 2013 в 10:21

parts = all_text.split('.') 

Отслеживать
ответ дан 27 фев 2013 в 9:47
3,028 13 13 серебряных знаков 14 14 бронзовых знаков
Тогда уж хоть re.compile(«[. \n]»).split(all_text) re.split(«[. \n]», all_text)
27 фев 2013 в 9:54
Как быть с троеточием?
27 фев 2013 в 10:07
Если голодному дать рыбу — он наестся один раз, а если научить ловить рыбу — он будет сыт всегда…
27 фев 2013 в 10:09
Так должно быть получше с составными разделителями: re.split(«\\b[. \\n]+(?=\\s)», all_text)
27 фев 2013 в 10:20

@moden . называется многоточием (по крайней мере называлось, когда я учился в школе). Во-вторых, есть и такой знак . . Можно подойти к заданию «творчески» (удалять пустые строки). filter(lambda x:not re.match(«^\s*$», x), re.split(«[. \n]», all_text) Правда есть подозрение, что знаки препинания в результирующем списке должны присутствовать. И тогда — просто поиск по шаблону [^. \n]+[. \n]+ . Что тоже не даёт 100% правильного результата «В 1998г. был дефолт».

27 фев 2013 в 10:31

s = "Properties are a little different. They need a special declaration since they're handled in a very different way. (Hmmmm. I may have figured out an obvious way around that, but I want to get this out the door first.) Here's how you'd mock out calls to a property. Note that unlike other calls, all the calls to an overridden property must be played back in order." def srtip_sent(str_): separators = ['.', '?', '!'] start = 0 s_split = [] for i in range(len(str_)): if s[i] in separators: s_split.append(str_[start:i+1]) start = i + 1 return map(lambda s: s.strip(), s_split) srtip_sent(s) ['Properties are a little different.', "They need a special declaration since they're handled in a very different way.", '(Hmmmm.', '.', '.', 'I may have figured out an obvious way around that, but I want to get this out the door first.', ") Here's how you'd mock out calls to a property.", 'Note that unlike other calls, all the calls to an overridden property must be played back in order.'] 

Не очень корректно работает с составными знаками, например с троеточием.

Отслеживать
ответ дан 27 фев 2013 в 10:05
892 6 6 серебряных знаков 16 16 бронзовых знаков

. а ещё с инициалами, типа А. С. Пушкин . А ещё с внутренними знаками препинания, наподобие «Что за хрень?» — поинтересовалась Алиса.

Razdel — сегментация русскоязычного текста на токены и предложения

Python-библиотека Razdel — часть проекта Natasha, делит русскоязычный текст на токены и предложения.

>>> from razdel import tokenize, sentenize >>> text = 'Кружка-термос на 0.5л (50/64 см³, 516;. )' >>> tokens = list(tokenize(text)) >>> tokens [Substring(start=0, stop=13, text='Кружка-термос'), Substring(start=14, stop=16, text='на'), Substring(start=17, stop=20, text='0.5'), Substring(start=20, stop=21, text='л'), Substring(start=22, stop=23, text='(') . ] >>> text = ''' . - "Так в чем же дело?" - "Не ра-ду-ют". . И т. д. и т. п. В общем, вся газета . ''' >>> list(sentenize(text)) [Substring(start=1, stop=23, text='- "Так в чем же дело?"'), Substring(start=24, stop=40, text='- "Не ра-ду-ют".'), Substring(start=41, stop=56, text='И т. д. и т. п.'), Substring(start=57, stop=76, text='В общем, вся газета')]

Скорость и качество сопоставимы или выше, чем у других открытых решений.

Ошибки на 1000 токенов Время обработки, секунды
Regexp-baseline 19 0.5
SpaCy 17 5.4
NLTK 130 3.1
MyStem 19 4.5
Moses 11 1.9
SegTok 12 2.1
SpaCy Russian Tokenizer 8 46.4
RuTokenizer 15 1.0
Razdel 7 2.6
Ошибки на 1000 предложений Время обработки, секунды
Regexp-baseline 76 0.7
SegTok 381 10.8
Moses 166 7.0
NLTK 57 7.1
DeepPavlov 41 8.5
Razdel 43 4.8

Число ошибок среднее по 4 датасетам: SynTagRus, OpenCorpora, GICRYA and RNC. Подробнее в репозитории Razdel.

В чём сложность?

В русском языке предложения обычно заканчиваются точкой, вопросительным или восклицательным знаком. Просто разделим текст регулярным выражением [. ]\s+ . Такое решение даст 76 ошибок на 1000 предложений.

… любая площадка с аудиторией от 3 тыс.| |человек является блогером.

… над ними с конца XVII в.| |стоял бей;

… в Камерном музыкальном театре им.| |Б.А. Покровского.

В след за операми «Идоменей» В.А.| |Моцарта – Р.| |Штрауса …

2.| |думал будет в финское консульство красивая длинная очередь …

г.| |билеты на поезда российских железных дорог …

В конце предложения многоточие, смайлик.

Кто предложит способ избавления от минусов — тому спасибо :)| |Посмотрел, призадумался…| |Вот это уже более неприятно, поскольку содержательность нарушится.

Цитаты, прямая речь, в конце предложения кавычка.

— невесты у вас в городе есть?»| |«Кому и кобыла невеста».

«Как хорошо, что я не такой!»| |Сейчас при переводе сделал фрейдстскую ошибку:»идология».

Razdel учитывает эти нюансы, сокращает число ошибок до 43 на 1000 предложений.

С токенами аналогичная ситуация. Хорошее базовое решение даёт регулярное выражение [а-яё-]+|[0-9]+|[^а-яё0-9 ] , оно делает 19 ошибок на 1000 токенов.

… В конце 1980|-х — начале 1990|-х … БС-|3 можно отметить слегка меньшую массу (3|,|6 т) — да и умерла.|.|. Понял ли девку, сокол?|!

Razdel сокращает число ошибок до 7 на 1000 токенов.

Принцип работы

Система построена на правилах. Принцип сегментации на токены и предложения одинаковый.

Сбор кандидатов

Находим в тексте всех кандидатов на конец предложения: точки, многоточия, скобки, кавычки.

6.| |Наиболее частый и при этом высоко оцененный вариант ответов «я рада»| |(13 высказываний, 25 баллов)| |– ситуации получения одобрения и поощрения.| |7.| |Примечательно, что в ответе «я знаю»| |оценен как максимально стереотипный, но лишь раз встречается ответ «я женщина»|;| |присутствуют высказывания «один брак – это всё, что меня ждет в этой жизни»| |и «рано или поздно придется рожать»|.| |Составители: В.| |П.| |Головин, Ф.| |В.| |Заничев, А.| |Л.| |Расторгуев, Р.| |В.| |Савко, И.| |И.| |Тучков.

Для токенов дробим текст на атомы. Внутри атома точно не проходит граница токена.

В| |конце| |1980|-|х| |-| |начале| |1990|-|х| БС|-|3| |можно| |отметить| |слегка| |меньшую| |массу| |(|3|,|6| |т|)| |—| |да| |и| |умерла|.|.|.| |Понял| |ли| |девку|,| |сокол|?|!

Объединение

Последовательно обходим кандидатов на разделение, убираем лишние. Используем список эвристик.

Элемент списка. Разделитель — точка или скобка, слева число или буква.

6.| |Наиболее частый и при этом высоко оцененный вариант ответов «я рада» (13 высказываний, 25 баллов) – ситуации получения одобрения и поощрения. 7.| |Примечательно, что в ответе «я знаю» …

Инициалы. Разделитель — точка, слева одна заглавная буква.

… Составители: В.| |П.| |Головин, Ф.| |В.| |Заничев, А.| |Л.| |Расторгуев, Р.| |В.| |Савко, И.| |И.| |Тучков.

Справа от разделителя нет пробела.

… но лишь раз встречается ответ «я женщина»|; присутствуют высказывания «один брак – это всё, что меня ждет в этой жизни» и «рано или поздно придется рожать»|.

Перед закрывающей кавычкой или скобкой нет знака конца предложения, это не цитата и не прямая речь.

6. Наиболее частый и при этом высоко оцененный вариант ответов «я рада»| |(13 высказываний, 25 баллов)| |– ситуации получения одобрения и поощрения. … «один брак – это всё, что меня ждет в этой жизни»| |и «рано или поздно придется рожать».

В результате остаётся два разделителя, считаем их концами предложений.

6. Наиболее частый и при этом высоко оцененный вариант ответов «я рада» (13 высказываний, 25 баллов) – ситуации получения одобрения и поощрения.| |7. Примечательно, что в ответе «я знаю» оценен как максимально стереотипный, но лишь раз встречается ответ «я женщина»; присутствуют высказывания «один брак – это всё, что меня ждет в этой жизни» и «рано или поздно придется рожать».| |Составители: В. П. Головин, Ф. В. Заничев, А. Л. Расторгуев, Р. В. Савко, И. И. Тучков.

Для токенов процедура аналогичная, правила другие.

Дробь или рациональное число.

— да и умерла.|.|. Понял ли девку, сокол?|!

Вокруг дефиса нет пробелов, это не начало прямой речи.

В конце 1980|-|х — начале 1990|-|х БС|-|3 можно отметить …

Всё что осталось считаем границами токенов.

В| |конце| |1980-х| |-| |начале| |1990-х| БС-3| |можно| |отметить| |слегка| |меньшую| |массу| |(|3,6| |т|)| |—| |да| |и| |умерла|. | |Понял| |ли| |девку|,| |сокол|?!

Ограничения

Правила в Razdel оптимизированы для аккуратно написанных текстов с правильной пунктуацией. Решение хорошо работает с новостными статьями, художественными текстами. На постах из социальных сетей, расшифровках телефонных разговоров качество ниже.

Если между предложениями нет пробела или в конце нет точки или предложение начинается с маленькой буквы, Razdel сделает ошибку.

Использование

natural_language_processing — чат пользователей, разработчиков проекта.

Александр Кукушкин

  • alex@alexkuk.ru
  • alexkuk
  • kuk

Лаборатория разрабатывает сервисы и коробочные продукты с использованием технологии Natasha, оказывает услуги анализа данных для российских компаний.

Деление строки по заглавным буквам в Python

Для деления по заглавным буквам строки записанной слитно, необходимо сначала изменить строку, добавить пробел перед заглавной буквой, а потом разделить строку по разделителю «пробел» стандартным методом str.split() .

Для добавления пробела перед заглавной буквой воспользуемся функцией re.sub() модуля re , а в регулярном выражении используем группу с захватом и обратную ссылку.

# исходная строка >>> line = 'МамаМылаРаму' >>> import re >>> re.sub(r'([А-Я])', r' \1', line).split() # ['Мама', 'Мыла', 'Раму'] 
  • ОБЗОРНАЯ СТРАНИЦА РАЗДЕЛА
  • Преобразование строки в число
  • Строку в список, кортеж или множество символов
  • Одинарные, двойные и тройные кавычки в строке Python
  • Вывод специальных символов в строке Python «как есть»
  • Объединение и повторение строк
  • Индексирование строк
  • Использование срезов строк
  • Cрез строки Python от заданного символа/знака до конца строки
  • Создание макета для печати базовыми методами строк
  • Способы форматирования текстовых строк
  • Подсчет повторений слов в тексте, деление строки на список слов
  • Удаление слова из строки Python по фрагменту или шаблону
  • Удаление пунктуации из строки
  • Деление строки по заглавным буквам
  • Создание отчетов и писем по шаблонам

ХОЧУ ПОМОЧЬ
ПРОЕКТУ

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *