в чем разница между,! и что?= в регулярном выражении?
Я искал смысл этих выражений, но не мог понять точную разницу между ними. Вот что они говорят:
-
?:сопоставьте выражение, но не захватите его. -
?=сопоставьте суффикс, но исключите его из захвата. -
?!матч, если суффикс отсутствует.
Я попытался использовать их в простом регулярном выражении и получил аналогичные результаты для всех. пример: следующие 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 ответа:
разницу между
?=и?!заключается в том, что первое требует, чтобы данное выражение соответствовало, а второе требует, чтобы оно не матч. Например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".
(?:...)имеет точно такой же эффект как просто(...), но он не возвращает эту часть в качестве подматча.