Регулярное выражение для слов из черного и белого списков

Я пытаюсь настроить регулярное выражение для черного и белого списков, отмечая слова из черного списка и игнорируя слова из белого списка. Вот правила:

  1. Я хочу увидеть, существует ли во входной строке слово или фраза из черного списка.
  2. Слова черного списка должны совпадать независимо от того, где они появляются (полное слово или как подстрока).
  3. Слова из белого списка (т.е. слова, которые заведомо считаются допустимыми, даже если они содержат слова из черного списка) не подлежат сопоставлению, если они представляют собой только полные слова.

Черный список слов, которые я хочу найти и сопоставить, если они найдены: ЗАЙЧИК, САД, ДЫРА.

Внесите в белый список чистые слова, которые можно игнорировать, даже если они содержат слова из черного списка: ЦЕЛЫЙ, САДОВНИК.

Я сделал следующее регулярное выражение с использованием отрицательного просмотра назад: (BUNNY|GARDEN|HOLE)(?<!\bWHOLE\b|\bGARDENER\b)

Мой глупый пример строки: Вся эта дыра - сплошная ошибка садовода-агронома.

Я бы ожидал, что подойдут только следующие: дырявый сплошной агардер

Это в основном работает, поскольку целое не совпадает, но целое совпадает, и агардер также подходит. Тем не менее, Gardener совпадает, даже если он находится в белом списке. Что мне не хватает?


person astrojeff    schedule 01.02.2021    source источник
comment
Прежде всего, необходимо уточнить, что вы подразумеваете под черным списком. По определению, если его нет в вашем белом списке, он не будет соответствовать. Так в чем разница между словом, находящимся в вашем черном списке, и словом, которого нет ни в одном из списков? И, если мы можем просто игнорировать черный список, подходит ли что-то подобное для ваших целей? \b(BUNNY|GARDEN|HOLE)\b   -  person Charlie Armstrong    schedule 02.02.2021
comment
Спасибо за вклад @ Чарли Армстронг. Обновил вопрос. Я пытаюсь определить, существует ли слово из черного списка во входной строке, но если слово из черного списка является частью слова из белого списка, игнорировать это совпадение.   -  person astrojeff    schedule 02.02.2021


Ответы (1)


Ты можешь использовать

\w*(?:BUNNY|GARDEN|HOLE)\w*\b(?<!\bWHOLE|\bGARDENER)

См. демонстрацию регулярных выражений.

Вариант без просмотра назад, но с просмотром вперед:

\b(?!(?:WHOLE|GARDENER)\b)\w*(?:BUNNY|GARDEN|HOLE)\w*\b

См. эту демонстрацию регулярного выражения.

Подробности:

  • \w* - ноль или более символов слова
  • (?:BUNNY|GARDEN|HOLE) - одна из обязательных частей слова
  • \w* - ноль или более символов слова
  • \b - граница слова
  • (?<!\bWHOLE|\bGARDENER) - отрицательный просмотр назад, при котором не удается найти совпадение, если целое слово, расположенное слева, равно WHOLE или GARDENER.

\b(?!(?:WHOLE|GARDENER)\b)\w*(?:BUNNY|GARDEN|HOLE)\w*\b сначала соответствует границе слова, затем не соответствует, если следующие символы представляют собой WHOLE или GARDENER целые слова, а затем сопоставляет слово с подстрокой BUNNY, GARDEN или HOLE в нем.

Замените \w на [a-zA-Z] или \p{L} (или [[:alpha:]]), если поддерживается, и вам нужно сопоставить только буквенные слова.

person Wiktor Stribiżew    schedule 01.02.2021