@0xC0CAC01A

Как это написать в виде регулярного выражения?

Предположим, что я хочу создать регулярное выражение, которое передает любую строку, содержащую "белый" или "серый" и "бегемот" или "гиппопотам", включая множественные числа, но не содержащие слово "голодный" или "злой", без учёта регистра.

Т.е. неформально говоря, я хочу что-то вроде: ("белый" OR "серый") AND ("бегемот[ы]" OR "гиппопотам[ы]") -"дикий" -"злой"

Должно пройти следующее:

"некоторые белые бегемоты выглядят великолепно"
"этот бегемот окрашен в серый цвет"
"белый и серый бегемоты"

Не должны проходить:

"Мне нравится белый цвет" (ни слова про бегемотов)
"белый дикий бегемот зашёл в реку" (дикий - вычёркивем)
"сероватый бегемот" (а не серый)

Как мне это сделать?

И кстати, есть ли библиотека (лучше на питоне), которая бы конвертировала удобочитаемые условия, например, как:

("белый" OR "серый") AND ("бегемот[ы]" OR "гиппопотам[ы]") -"дикий" -"злой",

в регулярные выражения?
  • Вопрос задан
  • 719 просмотров
Пригласить эксперта
Ответы на вопрос 4
@dodo512
^(?: (word1) | (word2) | ... )+
После прохода по строке, проверяем какие из сохраняющих групп участвовали в совпадении.
(?(id/name)yes-pattern|no-pattern) https://docs.python.org/3/library/re.html
Ещё потребуется атомарная группировка (?>...), которая не поддерживается в Python, но её можно имитировать с помощью позитивной опережающей проверки (?=...)
https://regex101.com/r/dbjy2E/1
pattern = r"""
(?xm)  
^
(?=
  (
    (?: \b (?P<a> белый | серый | красные ) \b
      | \b (?P<b> бегемот[ы]? |гиппопотам[ы]? ) \b
      | \b (?P<c> дикий | злой ) \b
      | \w+
      | [^\w\n]+
    )+
  )
)

(?(a)|(?!))
(?(b)|(?!))
(?(c)(?!)|)
"""
Ответ написан
dimonchik2013
@dimonchik2013
non progredi est regredi
если перед пацанми, то regexp замени на bagwords, слово тоже понтовое, и решение будет
Ответ написан
@silent-tempest
на js работает (только про розовых не матчит)
/^(?=.*(?:белы[йе]|серы[йе]))(?=.*(?:бегемоты?|гиппопотамы?))(?!.*(?:дики[йе]|зл(?:ой|ые))).*$/
Ответ написан
Комментировать
lidacriss
@lidacriss
wtf
/(?=.*?(белы[йе]|серы[йе]))(?=.*?(бегемот[ы]?|гиппопотам[ы]?))(?!.*?(дикий))(?!.*?(злой))/i

чет типа такого
https://jsfiddle.net/kwz7duqm/

upd
не заметил сначала, но у silent-tempest очень похожая регулярка получилась
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы