Отрицательный взгляд не работает с диапазоном символов
Я пытаюсь реализовать регулярное выражение, которое включает в себя все строки, которые имеют любое количество слов, но не могут сопровождаться: и игнорировать совпадение, если оно есть. Я решил использовать отрицательный взгляд вперед для этого.
/([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
не будет правильным выбором, если предполагается, что основной шаблон потребления должен совпадать, даже если он склеен с другими символами слова. Самый распространенный пример - совпадение чисел:
Провести проверку границы слова \b
после +
требовать, чтобы он дошел до конца слова.
([a-zA-Z]+\b)(?!:)