Отрицательный взгляд не работает с диапазоном символов

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

/([a-zA-Z]+)(?!:)/gm
string: lame:joker

Так как я использую диапазон символов, он соответствует одному символу за раз и игнорирует только последний символ перед: . Как я могу игнорировать весь матч в этом случае?

Ссылка на regex101: https://regex101.com/r/DlEmC9/1

2 ответа

Проблема связана с обратным отслеживанием : как только вы [a-zA-Z]+доходит до a, механизм отступает от неудачной позиции, повторно проверяет предварительное совпадение и находит совпадение, когда перед двоеточием есть по крайней мере две буквы, возвращая ту, за которой сразу не следует. См. Демонстрацию регулярного выражения : c в c:real не совпадает, так как нет позиции для возврата, и rea в real:c совпадает, потому что a сразу не следует.

Добавление неявного требования к отрицательному просмотру вперед

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

      [A-Za-z]+(?![A-Za-z]|:)
[A-Za-z]+(?![A-Za-z:])

См. Демонстрацию регулярных выражений . Поскольку оба [A-Za-z] а также : соответствуют одному символу, имеет смысл поместить их в один символьный класс, поэтому [A-Za-z]+(?![A-Za-z:]) лучше.

Предотвращение возврата к шаблону, подобному слову, с помощью границы слова

Как предлагает @scnerd, границы слов также могут помочь в этих ситуациях, но всегда есть уловка: значение границы слова зависит от контекста (см. Ряд if в объяснении границы слова ).

      [A-Za-z]+\b(?!:)

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

Когда граница слова не работает?

\bне будет правильным выбором, если предполагается, что основной шаблон потребления должен совпадать, даже если он склеен с другими символами слова. Самый распространенный пример - совпадение чисел:

  • \d+\b(?!:) совпадает в, но не в, а также и
  • \d+(?![\d:]) Матчи 12 в 12, а также 12c а также 12_, не в 12: Только.

Провести проверку границы слова \b после + требовать, чтобы он дошел до конца слова.

([a-zA-Z]+\b)(?!:)

Вот пример запуска.

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