Procurei o significado dessas expressões, mas não consegui entender a diferença exata entre elas. Isso é o que eles dizem:
?:
Corresponda a expressão, mas não a capture.?=
Corresponde a um sufixo, mas exclui-o da captura.?!
Corresponde se o sufixo estiver ausente.
Tentei usar isso em RegEx simples e obtive resultados semelhantes para todos. exemplo: as 3 expressões a seguir fornecem resultados muito semelhantes.
[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
RK Poddar
fonte
fonte
*
após os grupos, então eles são simplesmente ignorados.Respostas:
A diferença entre
?=
e?!
é que o primeiro exige que a expressão fornecida corresponda e o último exige que ela não corresponda. Por exemploa(?=b)
, corresponderá ao "a" em "ab", mas não ao "a" em "ac". Vistoa(?!b)
que corresponderá ao "a" em "ac", mas não ao "a" em "ab".A diferença entre
?:
e?=
é que?=
exclui a expressão de toda a correspondência,?:
mas não cria um grupo de captura. Assim, por exemplo,a(?:b)
irá corresponder ao "ab" em "abc", enquantoa(?=b)
irá corresponder apenas ao "a" em "abc".a(b)
corresponderia ao "ab" em "abc" e criaria uma captura contendo o "b".fonte
Por favor, verifique aqui: http://www.regular-expressions.info/lookaround.html para um tutorial muito bom e exemplos de lookahead em expressões regulares.
fonte
Para entender melhor, vamos aplicar as três expressões mais um grupo de captura e analisar cada comportamento.
()
grupo de captura - o regex entre parênteses deve ser correspondido e a correspondência criar um grupo de captura(?:)
grupo de não captura - o regex entre parênteses deve ser correspondido, mas não cria o grupo de captura(?=)
perspectiva positiva - afirma que a regex deve ser correspondida(?!)
olhar adiante negativo - afirma que é impossível corresponder ao regexVamos pedir
q(u)i
para sair .q
corresponde a qe o grupo de capturau
corresponde a u . A correspondência dentro do grupo de captura é realizada e um grupo de captura é criado. Então o motor continua comi
. Ei
vai corresponder a i . Esta última tentativa de correspondência foi bem-sucedida. qui é correspondido e um grupo de captura com u é criado.Vamos pedir
q(?:u)i
para sair . Novamente,q
corresponde a qe o grupo de não capturau
corresponde a u . A correspondência do grupo de não captura é obtida, mas o grupo de captura não é criado. Então o motor continua comi
. Ei
vai corresponder a i . Esta última tentativa de correspondência foi bem-sucedida. qui é compatívelVamos pedir
q(?=u)i
para sair . O lookahead é positivo e é seguido por outro token. Mais uma vez,q
corresponde q eu
partidas u . Novamente, a correspondência do lookahead deve ser descartada, de modo que o mecanismo recuei
da seqüência para u . A antecipação foi bem-sucedida, então o motor continua comi
. Masi
não pode corresponder a você . Portanto, essa tentativa de correspondência falha.Vamos pedir
q(?=u)u
para sair . O lookahead é positivo e é seguido por outro token. Mais uma vez,q
corresponde q eu
partidas u . A correspondência do lookahead deve ser descartada, de forma que o motor recueu
da string para u . A antecipação foi bem-sucedida, então o motor continua comu
. Eu
vai combinar com você . Portanto, esta tentativa de correspondência foi bem-sucedida. qu é compatívelVamos pedir
q(?!i)u
para sair . Mesmo nesse caso, a antecipação é positiva (porquei
não corresponde) e é seguida por outro token. Mais uma vez,q
corresponde q ei
não corresponde u . A correspondência do lookahead deve ser descartada, de forma que o motor recueu
da string para u . A antecipação foi bem-sucedida, então o motor continua comu
. Eu
vai combinar com você . Portanto, esta tentativa de correspondência foi bem-sucedida. qu é compatívelPortanto, em conclusão, a diferença real entre grupos de antevisão e de não captura é se você deseja apenas testar a existência ou testar e salvar a correspondência. Capturar grupo é caro, então use-o com cautela.
fonte
Tente comparar
foobar
com estes:A primeira regex corresponderá e retornará "bar" como primeira submatch -
(?=b)
corresponde ao 'b', mas não o consome, deixando-o para os parênteses seguintes.A segunda regex NÃO corresponderá, porque ela espera que "foo" seja seguido por algo diferente de 'b'.
(?:...)
tem exatamente o mesmo efeito que simples(...)
, mas não retorna essa parte como uma submatch.fonte
A maneira mais simples de entender as asserções é tratá-las como o comando inserido em uma expressão regular. Quando o mecanismo funciona para uma asserção, ele verifica imediatamente a condição descrita pela asserção. Se o resultado for verdadeiro, continue a executar a expressão regular.
fonte
Esta é a verdadeira diferença:
Se você não se importa, o conteúdo após "?:" Ou "? =", "?:" E "? =" São exatamente os mesmos. Ambos podem ser usados.
Mas se você precisar desse conteúdo para um processo posterior (não apenas corresponder a tudo. Nesse caso, você pode simplesmente usar "a (b)"). Você deve usar "? =". Porque "?:" Vai simplesmente passar.
fonte