Регулярное выражение Python, соответствующее полному или частичному слову

Есть ли способ, чтобы регулярное выражение соответствовало как можно большему количеству определенных слов? Например, если я ищу следующие слова: вчера, сегодня, завтра

Я хочу извлечь следующие полные слова:

  • Yest
  • вчера
  • пройдоха
  • тода
  • сегодня
  • Том
  • Tomor
  • завтра

    Следующие целые слова не должны совпадать (в основном, орфографические ошибки):

  • yesteray
  • tomorow
  • завтра
  • плоскоклюв

    Лучшее, что я мог придумать, это:

    \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 - конечная граница слова

    Смотрите демо Python:

    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/

    Другие вопросы по тегам