Токсизация слов с использованием регулярных выражений python
Я пытаюсь разделить строки на списки "тегов" в python. Разделение должно обрабатывать строки, такие как "HappyBirthday", и удалять большую пунктуацию, но сохранять дефисы и апострофы. Моя начальная точка:
tags = re.findall("([A-Z]{2,}(?=[A-Z]|$)|[A-Z][a-z]*)|\w+-\w+|[\w']+"
Я хотел бы повернуть эти образцы данных:
Jeff dog is un-American SomeTimes! BUT NOTAlways
В:
['Jeff's', 'dog', 'is', 'un-American', 'Some', 'Times', 'BUT', 'NOT', 'Always']
P.S. Мне жаль, что мое описание не очень хорошее. Я не уверен, как это объяснить, и в большинстве случаев у вас не получается с Google. Я надеюсь, что пример иллюстрирует это правильно.
Изменить: я думаю, мне нужно быть более точным, так что,
- Если слово загипнотизировано и капитал, например, "ООН-Американец", он сохранит его как одно слово, поэтому выход будет "UN-American"
- Если дефис имеет пространство на одной или обеих сторонах, a la 'THIS- is' или 'This - is', он должен игнорировать hypen и производить [ "THIS", "is" ] и ["THIS", "есть" ] уважительно,
- и просто для апострофа, если его в середине слова, такого как "What's IsTalled", он должен произвести [ "Что есть", "Это", "Вызывается" ]
Ответы
Ответ 1
Я предлагаю следующее:
re.findall("[A-Z]{2,}(?![a-z])|[A-Z][a-z]+(?=[A-Z])|[\'\w\-]+",s)
Это дает для вашего примера:
["Jeff's", 'dog', 'is', 'un-American', 'Some', 'Times', 'BUT', 'NOT', 'Always']
Объяснение: RegExp состоит из 3 альтернатив:
-
[A-Z]{2,}(?![a-z])
соответствует словам со всеми буквами
-
[A-Z][a-z]+(?=[A-Z])
соответствует словам с первым письмом. Внешний вид (?=[A-Z])
останавливает совпадение перед следующей заглавной буквой
-
[\'\w\-]+
соответствует всем остальным, то есть словам, которые могут содержать '
и -
.
Ответ 2
Чтобы обрабатывать ваши отредактированные случаи, я бы изменил phynfo (+1) отличный ответ на
>>> s = """Jeff UN-American Un-American un-American
SomeTimes! BUT NOTAlways This- THIS-
What'sItCalled someTimes"""
>>> re.findall("[A-Z\-\']{2,}(?![a-z])|[A-Z\-\'][a-z\-\']+(?=[A-Z])|[\'\w\-]+",s)
["Jeff's", 'UN-', 'American', 'Un-', 'American', 'un-American',
'Some', 'Times', 'BUT', 'NOT', 'Always', 'This-', 'THIS-',
"What's", 'It', 'Called' 'someTimes']
Вам нужно четко определить правила для вашего желаемого поведения. Токенизация не является определением, вы должны иметь что-то подобное правилам phynfo. Например, у вас есть правило, что 'NOTAlways'
должно перейти к 'NOT'
и 'Always'
, и что дефисы должны быть сохранены. Таким образом, 'UN-American'
разделяется, подобно тому, как UNAmerican будет разделен. Вы можете попробовать определить дополнительные правила, но вам нужно четко указать, какое правило применяется при перекрытии правил.