Regex: что означает (?!...)?

Следующее регулярное выражение находит текст между подстроками FTW и ODP.

/FTW(((?!FTW|ODP).)+)ODP+/

Что делает (?!... )?

Ответ 1

(?!regex) - это отрицательная обратная сторона нулевой ширины. Он будет проверять символы в текущей позиции курсора и вперед, тестируя, что они НЕ соответствуют предоставленному регулярному выражению, а затем возвращают курсор обратно туда, где он был запущен.

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

/
 FTW           # Match Characters 'FTW'
 (             # Start Match Group 1
  (             # Start Match Group 2
   (?!FTW|ODP)   # Ensure next characters are NOT 'FTW' or 'ODP', without matching
   .             # Match one character
  )+            # End Match Group 2, Match One or More times
 )             # End Match Group 1
 OD            # Match characters 'OD'
 P+            # Match 'P' One or More times
/

Итак - Охота на FTW, а затем захватите, ища ODP+, чтобы закончить нашу строку. Также убедитесь, что данные между FTW и ODP+ не содержат FTW или ODP

Ответ 2

От perldoc:

A отрицательное прогнозное выражение с нулевой шириной. Например, /foo(?!bar)/ соответствует любому вхождению "foo" , за которым не следует "bar". Обратите внимание, однако, что внешний вид и внешний вид - это не одно и то же. Вы не можете использовать это для поиска.

Если вы ищете "бар", которому не предшествует "foo" , /(?!foo)bar/ не будет делать то, что вы хотите. Это потому, что (?!foo) просто говорит, что следующая вещь не может быть "foo" - и это не так, это "бар", поэтому "foobar" будет соответствовать. Для этого вам нужно сделать что-то вроде /(?!foo)...bar/. Мы говорим "нравится", потому что случай вашего "bar" не имеет трех символов перед ним. Вы можете это сделать так: /(?:(?!foo)...|^.{0,2})bar/. Иногда еще проще сказать:

if (/bar/ && $` !~ /foo$/)

Ответ 3

Это означает, что "не следует...". Технически это то, что называется негативный взгляд, в котором вы можете заглянуть в то, что впереди в строке, не захватывая его. Это класс утверждения с нулевой шириной, что означает, что такие выражения не фиксируют какую-либо часть выражения.

Ответ 4

Программист должен был набирать слишком быстро. Некоторые символы в шаблоне перевернулись. Исправлено:

/WTF(((?!WTF|ODP).)+)ODP+/

Ответ 5

Regex

/FTW(((?!FTW|ODP).)+)ODP+/

совпадает с первым FTW, после которого не следует ни FTW, ни ODP, а затем все следующие символы до первого ODP (но если есть FTW где-то в них не будет соответствия), то все буквы P следуют.

Итак, в строке:

FTWFTWODPFTWjjFTWjjODPPPPjjODPPPjjj

он будет соответствовать полужирной части

FTWFTWODPFTWjj FTWjjODPPPP jjODPPPjjj

Ответ 6

'?! на самом деле является частью '(?!...)', это означает, что все, что внутри, должно НЕ совпадать в этом месте.