Regex: что делает (?! ...) имели в виду?

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

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

что значит (?!...) делать?

6 ответов


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

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

/
 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


С perldoc:

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

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

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

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


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

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

выражение

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

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

в строку:

FTWFTWODPFTWjjFTWjjODPPPPjjODPPPjjj

он будет соответствовать жирная часть

FTWFTWODPFTWjjFTWjjODPPPPjjODPPPjjj


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