Регулярное выражение — Сопоставление слов в одном предложении с отрицательным внешним видом

#regex #regex-lookarounds #sentence

Вопрос:

Я пытаюсь сопоставить слово (хорошее), если другого слова (плохого) нет в том же предложении. Я хочу сделать это с помощью lookaround, так как я хочу, чтобы в полученные результаты было включено только первое слово (хорошее).

Вот мое регулярное выражение:

 (?<!bbadb[^.])bgoodb(?![^.] bbadb)
 

Это работает во всех случаях, за исключением случаев, когда слово, которое я ищу (хорошее), предшествует другому слову (плохое).

Таким образом, в следующих примерах результаты выглядят следующим образом:

  1. ТЕСТ 1: Хороший пример неправильного регулярного выражения. (нет совпадений — ПРОПУСК)
  2. ТЕСТ 2: Плохой пример хорошего регулярного выражения. (совпадение найдено — ОШИБКА)
  3. ТЕСТ 3: Плохой пример. Хорошее регулярное выражение. (совпадение найдено — ПРОПУСК)
  4. ТЕСТ 4: Хороший пример. Плохое регулярное выражение. (совпадение найдено — ПРОПУСК)

Может кто-нибудь, пожалуйста, указать мне, чего мне здесь не хватает? Вот мой тест на regex101.com.

Комментарии:

1. Так bad не должно ли быть после good в одном предложении?

2. @анубхава. Да, «плохое» не должно стоять перед или после «хорошего» в одном и том же предложении. Если «плохо» появляется после «хорошо», мое регулярное выражение работает. Но регулярное выражение терпит неудачу, если «плохо» появляется перед «хорошо» в том же предложении.

3. Просто хочу отметить, что это также возможно, сопоставив то, что вам не нужно, но зафиксировав то, что вы хотите : [^.]*bbadb[^.]*|(bgoodb) (Если вы можете это использовать, зависит от вашей задачи. Это требует программной проверки, установлена ли группа 1)

Ответ №1:

Вы можете использовать это регулярное выражение:

 (?:^|.)(?:(?!b(?:bad|good)b)[^.])*(bgoodb)(?![^.] bbadb)
 

Демонстрация регулярных выражений

Сведения о регулярном выражении:

  • (?:^|.) : Совпадение начальной позиции или точки
  • (?:(?!b(?:bad|good)b)[^.])* : Сопоставьте символ без точки, если у него нет слова good или bad впереди. Повторите это совпадение 0 или более раз
  • (bgoodb) : Соответствует полному слову good
  • (?![^.] bbadb) : Отрицательный взгляд, чтобы утверждать, что у нас нет одного или нескольких символов без точек, за которыми следует слово, bad перед текущей позицией

Комментарии:

1. Вот все модульные тесты

Ответ №2:

Если квантор в поиске поддерживается, вы можете при необходимости повторить класс символов, исключая соответствие новой строке.

 (?<!bbadb[^.n]*)bgoodb(?![^.n] bbadb)
 

Шаблон совпадает:

  • (?<!bbadb[^.n]*) Отрицательный взгляд назад, утверждение слева-это не слово bad , за которым следуют необязательные символы, исключающие a . или новую строку
  • bgoodb Сопоставьте слово good
  • (?![^.n] bbadb) Отрицательный внешний вид, утверждение справа не является необязательным, исключая символы . или новую строку и слово bad

Демонстрация регулярных выражений

Комментарии:

1. Это хорошее регулярное выражение для таких вариантов, как современный Javascript

2. Это очень чистое выражение. Я использую его в C# .NET Core, и кванторы поддерживаются в lookbehind. Поэтому я воспользуюсь вашим решением. Спасибо!