Búsqueda hacia adelante, hacia atrás y grupos atómicos de expresiones regulares
Encontré estas cosas en mi cuerpo de expresiones regulares pero no tengo idea de para qué puedo usarlas. ¿Alguien tiene ejemplos para que pueda intentar entender cómo funcionan?
(?=) - positive lookahead
(?!) - negative lookahead
(?<=) - positive lookbehind
(?<!) - negative lookbehind
(?>) - atomic group
Ejemplos
Dada la cadena foobarbarfoo
:
bar(?=bar) finds the 1st bar ("bar" which has "bar" after it)
bar(?!bar) finds the 2nd bar ("bar" which does not have "bar" after it)
(?<=foo)bar finds the 1st bar ("bar" which has "foo" before it)
(?<!foo)bar finds the 2nd bar ("bar" which does not have "foo" before it)
También puedes combinarlos:
(?<=foo)bar(?=bar) finds the 1st bar ("bar" with "foo" before it and "bar" after it)
Definiciones
Mirar hacia adelante en positivo(?=)
Encuentre la expresión A donde sigue la expresión B:
A(?=B)
Mirar hacia adelante negativo(?!)
Encuentre la expresión A donde la expresión B no sigue:
A(?!B)
Mirar detrás de lo positivo(?<=)
Encuentre la expresión A donde la expresión B precede:
(?<=B)A
Mira detrás de lo negativo(?<!)
Encuentre la expresión A donde la expresión B no precede:
(?<!B)A
Grupos atómicos(?>)
Un grupo atómico sale de un grupo y descarta patrones alternativos después del primer patrón coincidente dentro del grupo (el retroceso está deshabilitado).
(?>foo|foot)s
aplicadofoots
coincidirá con su primera alternativafoo
, luego fallará porques
no sigue inmediatamente y se detendrá porque el retroceso está deshabilitado
Un grupo no atómico permitirá retroceder; si falla la coincidencia posterior, retrocederá y utilizará patrones alternativos hasta que se encuentre una coincidencia para la expresión completa o se agoten todas las posibilidades.
(foo|foot)s
aplicado alfoots
testamento:- coincide con su primera alternativa
foo
, luego falla porques
no sigue inmediatamentefoots
y retrocede hasta su segunda alternativa; - haga coincidir su segunda alternativa
foot
, luego tenga éxito comos
sigue inmediatamentefoots
y deténgase.
- coincide con su primera alternativa
Algunos recursos
- http://www.regular-expressions.info/lookaround.html
- http://www.rexegg.com/regex-lookarounds.html
Probadores en línea
- https://regex101.com
Las búsquedas son afirmaciones de ancho cero. Comprueban una expresión regular (hacia la derecha o la izquierda de la posición actual, según esté delante o detrás), tienen éxito o fallan cuando encuentran una coincidencia (según si es positiva o negativa) y descartan la parte coincidente. No consumen ningún carácter: la coincidencia de expresiones regulares que les siguen (si las hay) comenzará en la misma posición del cursor.
Lea regular-expression.info para obtener más detalles.
- Previsión positiva:
Sintaxis:
(?=REGEX_1)REGEX_2
Coincide sólo si REGEX_1 coincide; después de hacer coincidir REGEX_1, la coincidencia se descarta y la búsqueda de REGEX_2 comienza en la misma posición.
ejemplo:
(?=[a-z0-9]{4}$)[a-z]{1,2}[0-9]{2,3}
REGEX_1 es [a-z0-9]{4}$
el que coincide con cuatro caracteres alfanuméricos seguidos del final de la línea.
REGEX_2 es [a-z]{1,2}[0-9]{2,3}
el que coincide con una o dos letras seguidas de dos o tres dígitos.
REGEX_1 se asegura de que la longitud de la cadena sea efectivamente 4, pero no consume ningún carácter para que la búsqueda de REGEX_2 comience en la misma ubicación. Ahora REGEX_2 se asegura de que la cadena coincida con otras reglas. Sin anticipación, coincidiría con cadenas de tres o cinco longitudes.
- Previsión negativa
Sintaxis:
(?!REGEX_1)REGEX_2
Coincide sólo si REGEX_1 no coincide; después de verificar REGEX_1, la búsqueda de REGEX_2 comienza en la misma posición.
ejemplo:
(?!.*\bFWORD\b)\w{10,30}$
La parte de anticipación busca el FWORD
en la cadena y falla si lo encuentra. Si no lo encuentra FWORD
, la búsqueda anticipada se realiza correctamente y la siguiente parte verifica que la longitud de la cadena esté entre 10 y 30 y que contenga solo caracteres de palabra.a-zA-Z0-9_
La mirada hacia atrás es similar a la mirada hacia adelante: simplemente mira detrás de la posición actual del cursor. Algunos tipos de expresiones regulares como javascript no admiten afirmaciones retrospectivas. Y la mayoría de las versiones que lo admiten (PHP, Python, etc.) requieren que la parte retrospectiva tenga una longitud fija.
- Los grupos atómicos básicamente descartan/olvidan los tokens posteriores del grupo una vez que un token coincide. Consulte esta página para ver ejemplos de grupos atómicos.
Por qué: suponga que está jugando a Wordle y ha ingresado "ant". (Sí, palabra de tres letras, es sólo un ejemplo, tranquilo)
La respuesta aparece en blanco, amarillo, verde y tiene una lista de palabras de tres letras que desea utilizar una expresión regular para buscar. ¿Como lo harias?
Para empezar podrías empezar con la presencia de la t en la tercera posición:
[a-z]{2}t
Podríamos mejorar si notamos que no tenemos una
[b-z]{2}t
Podríamos mejorar aún más diciendo que la búsqueda debe tener una n.
(?=.*n)[b-z]{2}t
o descomponerlo;
(?=.*n) - Mire hacia adelante y verifique que la coincidencia tenga una n, puede tener cero o más caracteres antes de esa n.
[bz]{2}: dos letras distintas de una 'a' en las dos primeras posiciones;
t - literalmente una 't' en la tercera posición