Извлечение целых слов - PullRequest
       15

Извлечение целых слов

8 голосов
/ 19 апреля 2011

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

В настоящее время я извлекаю все алфавитные последовательности с помощью '[a-z]+'.Это нормальное приближение, но оно тянет с собой много мусора.

В идеале Я хотел бы получить регулярное выражение (не обязательно красивое или эффективное), которое извлекает все алфавитноепоследовательности, разделенные естественными разделителями слов (например, [/-_,.: ] и т. д.), и игнорирующие любые алфавитные последовательности с недопустимыми границами.

Однако я также был бы рад просто получить все алфавитные последовательности, которые НЕ являютсярядом с номером.Так, например, 'pie21' НЕ будет извлекать 'pie', но 'http://foo.com' будет извлекать ['http', 'foo', 'com'].

Я пытался lookahead и lookbehind утверждений, но они применялись для каждого символа (так что дляпример re.findall('(?<!\d)[a-z]+(?!\d)', 'pie21') вернул бы 'pi', когда я хочу, чтобы он ничего не возвращал).Я попытался обернуть альфа-часть термином ((?:[a-z]+)), но это не помогло.

Подробнее: Данные представляют собой базу данных электронной почты, поэтому в основном это обычный английский с обычнымчисла, но иногда есть чепухи вроде GIHQ4NWL0S5SCGBDD40ZXE5IDP13TYNEA и AC7A21C0, которые я бы хотел полностью игнорировать.Я предполагаю, что любая алфавитная последовательность с числом в ней является мусором.

Ответы [ 4 ]

17 голосов
/ 19 апреля 2011

Если вы ограничиваете себя буквами ASCII, то используйте (с установленной опцией re.I)

\b[a-z]+\b

\b - это привязка границы слова, совпадающая только в начале и в конце буквенно-цифровых «слов». Таким образом, \b[a-z]+\b соответствует pie, но не pie21 или 21pie.

Чтобы разрешить и другие не-ASCII буквы, вы можете использовать что-то вроде этого:

\b[^\W\d_]+\b

, который также допускает символы с акцентом и т. Д. Вам может потребоваться установить параметр re.UNICODE, особенно при использовании Python 2, для того, чтобы позволить стенде \w соответствовать буквам, отличным от ASCII.

[^\W\d_] в качестве отрицательного символьного класса допускаются любые буквенно-цифровые символы, кроме цифр и подчеркивания.

3 голосов
/ 19 апреля 2011

Вы знакомы с границами слова? (\b).Вы можете извлекать слова, используя \b вокруг последовательности и сопоставляя алфавит в пределах:

\b([a-zA-Z]+)\b

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

Вы можете просмотреть последовательность \b и другие в руководстве python

РЕДАКТИРОВАТЬ Кроме того, если вы ищетео числе, следующем или предшествующем матчу, вы можете использовать отрицательный прогноз вперед / назад:

(?!\d)   # negative look-ahead for numbers
(?<!\d)  # negative look-behind for numbers
2 голосов
/ 19 апреля 2011

А как же:

import re
yourString="pie 42 http://foo.com GIHQ4NWL0S5SCGBDD40ZXE5IDP13TYNEA  pie42"
filter (lambda x:re.match("^[a-zA-Z]+$",x),[x for x in set(re.split("[\s:/,.:]",yourString))])

Обратите внимание, что:

  • split разбивает вашу строку на потенциальных кандидатов => возвращает список «потенциальных слов»
  • set делает фильтрацию уникальностью => преобразует список в набор, таким образом удаляя записи, появляющиеся более одного раза. Этот шаг не является обязательным.
  • уменьшает количество кандидатов: берет список, применяет функцию теста к каждому элементу и возвращает список элемента, прошедшего тест. В нашем случае тестовая функция является «анонимной»
  • лямбда: анонимная функция, берущая элемент и проверяющая, является ли это слово (только верхняя или нижняя буквы)

РЕДАКТИРОВАТЬ : добавлены некоторые пояснения

0 голосов
/ 06 декабря 2017

Пример кода

print re.search(ur'(?u)ривет\b', ur'Привет')
print re.search(ur'(?u)\bривет\b', ur'Привет')

или

s = ur"abcd ААБВ"
import re
rx1 = re.compile(ur"(?u)АБВ")
rx2 = re.compile(ur"(?u)АБВ\b")
rx3 = re.compile(ur"(?u)\bАБВ\b")
print rx1.findall(s)
print rx2.findall(s)
print rx3.findall(s)
...