Я искал значения этих выражений, но не мог понять точной разницы между ними. Вот что они говорят:
?:
Сопоставьте выражение, но не фиксируйте его.?=
Сопоставьте суффикс, но исключите его из захвата.?!
Соответствует, если суффикс отсутствует.
Я пробовал использовать их в простом RegEx и получил аналогичные результаты для всех. Пример: следующие 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]+)*
javascript
regex
РК Поддар
источник
источник
*
после групп, поэтому они просто игнорируются.Ответы:
Разница между
?=
и?!
заключается в том, что первое требует, чтобы данное выражение соответствовало, а второе требует, чтобы оно не совпадало. Например,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».источник
Пожалуйста, проверьте здесь: http://www.regular-expressions.info/lookaround.html, чтобы найти очень хорошее руководство и примеры просмотра вперед в регулярных выражениях.
источник
Чтобы лучше понять, давайте применим три выражения плюс группу захвата и проанализируем каждое поведение.
()
группа захвата - регулярное выражение внутри круглых скобок должно быть сопоставлено, и совпадение создает группу захвата(?:)
группа без захвата - регулярное выражение внутри круглых скобок должно совпадать, но не создает группу захвата(?=)
позитивный взгляд в будущее - утверждает, что регулярное выражение должно быть сопоставлено(?!)
отрицательный взгляд в будущее - утверждает, что невозможно сопоставить регулярное выражениеПодаем заявку
q(u)i
на выход .q
соответствует q, а группа захватаu
соответствует u . Будет выполнено совпадение внутри группы захвата, и группа захвата будет создана. Итак, двигатель продолжает работатьi
. Иi
будет соответствовать i . Эта последняя попытка совпадения успешна.qui сопоставляется, и создается группа захвата с u .Подаем заявку
q(?:u)i
на выход . Опять же,q
соответствует q, а группа без захватаu
соответствует u . Выбирается совпадение из группы без захвата, но группа захвата не создается. Итак, двигатель продолжает работатьi
. Иi
будет соответствовать я . Эта последняя попытка совпадения успешна. qui совпадаетПодаем заявку
q(?=u)i
на выход . Предварительный просмотр положительный, за ним следует другой токен. Опять же,q
соответствует q иu
соответствует u . Опять же, совпадение из опережающего просмотра должно быть отброшено, поэтому движок отступает отi
строки к u . Предварительный просмотр был успешным, поэтому двигатель продолжает работуi
. Ноi
не может соответствовать тебе . Итак, эта попытка совпадения не удалась.Подаем заявку
q(?=u)u
на выход . Предварительный просмотр положительный, за ним следует другой токен. Опять же,q
соответствует q иu
соответствует u . Совпадение из опережающего просмотра должно быть отброшено, поэтому движок отступает отu
строки к u . Предварительный просмотр был успешным, поэтому двигатель продолжает работуu
. Иu
будет соответствовать U . Итак, эта попытка совпадения успешна.qu соответствуетПодаем заявку
q(?!i)u
на выход . Даже в этом случае просмотр вперед положительный (потомуi
что не совпадает), и за ним следует другой токен. Опять же,q
соответствует q иi
не соответствует u . Совпадение из опережающего просмотра должно быть отброшено, поэтому движок отступает отu
строки к u . Предварительный просмотр был успешным, поэтому двигатель продолжает работуu
. Иu
будет соответствовать U . Итак, эта попытка совпадения успешна.qu соответствуетИтак, в заключение, реальная разница между прогнозирующими и не захватывающими группами заключается в том, хотите ли вы просто проверить наличие или проверить и сохранить совпадение. Группы захвата дороги, поэтому используйте их с умом.
источник
Попробуйте сопоставить
foobar
с ними:Первое регулярное выражение будет соответствовать и вернет «bar» в качестве первого
(?=b)
подчиненного совпадения - соответствует 'b', но не использует его, оставляя его в следующих скобках.Второе регулярное выражение НЕ будет соответствовать, потому что оно ожидает, что за "foo" будет что-то отличное от 'b'.
(?:...)
имеет тот же эффект, что и простой(...)
, но не возвращает эту часть в качестве подчиненного совпадения.источник
Самый простой способ понять утверждения - рассматривать их как команду, вставленную в регулярное выражение. Когда движок работает с утверждением, он немедленно проверяет состояние, описанное в утверждении. Если результат верен, продолжайте выполнение регулярного выражения.
источник
Вот настоящая разница:
Если вам все равно, содержимое после "?:" Или "? =", "?:" И "? =" Одинаковы. Оба они подходят для использования.
Но если вам нужен этот контент для дальнейшей обработки (а не просто для соответствия целому. В этом случае вы можете просто использовать «a (b)»), вы должны вместо этого использовать «? =». Причина "?:" Будет просто через это прочь.
источник