Регулярное выражение Python, соответствующее полному или частичному слову
Есть ли способ, чтобы регулярное выражение соответствовало как можно большему количеству определенных слов? Например, если я ищу следующие слова: вчера, сегодня, завтра
Я хочу извлечь следующие полные слова:
Следующие целые слова не должны совпадать (в основном, орфографические ошибки):
Лучшее, что я мог придумать, это:
\b((tod(a(y)?)?)|(tom(o(r(r(o(w)?)?)?)?)?)|(yest(e(r(d(a(y)?)?)?)?)?))\b
(Пример)
Примечание: я мог бы реализовать это с помощью конечного автомата, но подумал, что это было бы смешно, чтобы получить регулярное выражение для этого. К сожалению, все, что я придумываю, смехотворно сложно, и я надеюсь, что я что-то пропустил.
2 ответа
Регулярное выражение, которое вы ищете, должно включать дополнительные группы с чередованиями.
\b(yest(?:e(?:r(?:d(?:ay?)?)?)?)?|tod(?:ay?)?|tom(?:o(?:r(?:r(?:ow?)?)?)?)?)\b
Посмотреть демо
Обратите внимание, что \b
границы слов очень важны, так как вы хотите соответствовать только целым словам.
Regex объяснение:
\b
- ведущая граница слова(yest(?:e(?:r(?:d(?:ay?)?)?)?)?|tod(?:ay?)?|tom(?:o(?:r(?:r(?:o(?:w)?)?)?)?)?)
- сопоставление группы захватаyest(?:e(?:r(?:d(?:ay?)?)?)?)?
-yest
,yeste
,yester
,yesterd
,yesterda
или жеyesterday
tod(?:ay?)?
-tod
или жеtoda
или жеtoday
tom(?:o(?:r(?:r(?:o(?:w)?)?)?)?)?
-tom
,tomo
,tomor
,tomorr
,tomorro
, или жеtomorrow
\b
- конечная граница слова
import re
p = re.compile(ur'\b(yest(?:e(?:r(?:d(?:ay?)?)?)?)?|tod(?:ay?)?|tom(?:o(?:r(?:r(?:ow?)?)?)?)?)\b', re.IGNORECASE)
test_str = u"yest\nyeste\nyester\nyesterd\nyesterda\nyesterday\ntod\ntoda\ntoday\ntom\ntomo\ntomor\ntomorr\ntomorro\ntomorrow\n\nyesteray\ntomorow\ntommorrow\ntody\nyesteday"
print(p.findall(test_str))
# => [u'yest', u'yeste', u'yester', u'yesterd', u'yesterda', u'yesterday', u'tod', u'toda', u'today', u'tom', u'tomo', u'tomor', u'tomorr', u'tomorro', u'tomorrow']
Разделите все допустимые слова или подстроки слов, как показано ниже. Это будет соответствовать только правильному написанию по желанию
^(?|yest|yesterday|tod|today)\b
Протестировал это уже на https://regex101.com/