в чем разница между,! и что?= в регулярном выражении?


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

  • ?: сопоставьте выражение, но не захватите его.
  • ?= сопоставьте суффикс, но исключите его из захвата.
  • ?! матч, если суффикс отсутствует.

Я попытался использовать их в простом регулярном выражении и получил аналогичные результаты для всех. пример: следующие 3 выражения дают очень похожие результаты.

  • [a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?!.[a-zA-Z0-9]+)*
  • [a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?=.[a-zA-Z0-9]+)*
  • [a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?:.[a-zA-Z0-9]+)*
4 63

4 ответа:

разницу между ?= и ?! заключается в том, что первое требует, чтобы данное выражение соответствовало, а второе требует, чтобы оно не матч. Например a(?=b) будет соответствовать "a" в "ab", но не "a"В " ac". Тогда как a(?!b) будет соответствовать "a" В "ac", но не "a"в " ab".

разницу между ?: и ?= Это ?= исключает выражение из всего матча в то время как ?: просто не создает группу захвата. Так, например,a(?:b) будет соответствовать "ab" в "abc", в то время как a(?=b) будет соответствовать только "a"в " abc". a(b) будет соответствовать "ab "в" abc"и создать захват, содержащий "b".

?:  is for non capturing group
?=  is for positive look ahead
?!  is for negative look ahead
?<= is for positive look behind
?<! is for negative look behind

пожалуйста, проверьте здесь:http://www.regular-expressions.info/lookaround.html для очень хорошего учебника и примеров на lookahead в регулярных выражениях.

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

  • ()захват группы - регулярное выражение внутри круглой скобки должно быть сопоставлено, и совпадение создает группу захвата
  • (?:)не захват группы - регулярное выражение внутри круглой скобки должно быть сопоставлено, но не создает группу захвата
  • (?=)позитивный взгляд впереди - утверждает, что регулярное выражение должно соответствовать
  • (?!)отрицательное смотреть вперед - утверждает, что невозможно сопоставить регулярное выражение

давайте применим q(u)i до закрыть. q игр q и группа захвата u игр u. Выполняется сопоставление внутри группы захвата и создается группа захвата. Так что двигатель продолжает с i. И i будет соответствовать я. Эта последняя попытка матча успешна. qui соответствует и захват группы с u это.

давайте применим q(?:u)i до закрыть. Опять,q игр q и группа без захвата u игр u. Совпадение из группы без захвата берется, но группа захвата не создается. Так что двигатель продолжает с i. И i будет соответствовать я. Эта последняя попытка матча успешна. qui соответствует

давайте применим q(?=u)i до закрыть. В впередсмотрящих положительное, и последовал еще один знак. Опять,q игр q и u игр u. Опять же, матч с lookahead должен быть отброшен, поэтому двигатель отступает от i в строке u. Lookahead был успешным, поэтому двигатель продолжает работать i. Но i не соответствует u. Так что эта попытка оказывается неудачной.

давайте применим q(?=u)u до закрыть. В впередсмотрящих положительное, и последовал еще один знак. Опять,q игр q и u игр u. Совпадение с lookahead должно быть отброшено, поэтому двигатель отступает от u в строке u. Lookahead был успешным, поэтому двигатель продолжает работу с u. И u будет соответствовать u. Так что эта попытка матча удалась. вопр соответствует

давайте применим q(?!i)u до закрыть. Даже в этом случае lookahead является положительным (потому что i не совпадает) и сопровождается другим маркером. Опять,q игр q и i не соответствует u. Совпадение с lookahead должно быть отброшено, поэтому двигатель отступает от u в строке u. Lookahead был успешным, поэтому двигатель продолжает работу с u. И u будет соответствовать u. Так что эта попытка матча удалась. вопр соответствует

Итак, в заключение, реальная разница между lookahead и группами без захвата заключается в том, хотите ли вы просто проверить существование или проверить и сохранить матч. Захват группы стоят дорого, так что используйте его разумно.

попробуй сравнить foobar против:

/foo(?=b)(.*)/
/foo(?!b)(.*)/

первое регулярное выражение будет соответствовать и вернет "бар" как первый submatch -(?=b) соответствует 'b', но не использует его, оставляя его для следующих скобок.

второе регулярное выражение не будет соответствовать, потому что он ожидает, что "foo" будет сопровождаться чем-то отличным от "b".

(?:...) имеет точно такой же эффект как просто (...), но он не возвращает эту часть в качестве подматча.