Regular Expressions
Cuantitativos codiciosos y perezosos
Buscar..
Parámetros
Cuantificadores | Descripción |
---|---|
? | Haga coincidir el carácter o subexpresión anterior 0 o 1 veces (preferiblemente 1). |
* | Haga coincidir el carácter o subexpresión anterior 0 o más veces (tantas como sea posible). |
+ | Haga coincidir el carácter o subexpresión anterior 1 o más veces (tantas como sea posible). |
{n} | Haga coincidir el carácter o subexpresión precedente exactamente n veces. |
{min,} | Haga coincidir el carácter o subexpresión anterior un mínimo o más veces (el mayor número posible). |
{0,max} | Haga coincidir el carácter o subexpresión anterior máximo o menos veces (lo más cerca posible del máximo ). |
{min,max} | Haga coincidir el carácter o subexpresión precedente al menos un mínimo de veces, pero no más de un máximo de veces (lo más cerca posible del máximo ). |
Cuantificadores perezosos | Descripción |
?? | Haga coincidir el carácter o subexpresión anterior 0 o 1 veces (preferiblemente 0). |
*? | Haga coincidir el carácter o subexpresión anterior 0 o más veces (el menor número posible). |
+? | Haga coincidir el carácter o subexpresión anterior 1 o más veces (lo menos posible). |
{n}? | Haga coincidir el carácter o subexpresión precedente exactamente n veces. No hay diferencia entre la versión codiciosa y la perezosa. |
{min,}? | Haga coincidir el carácter o subexpresión anterior mín. O más veces (lo más cerca posible al mínimo ). |
{0,max}? | Haga coincidir el carácter o subexpresión precedente como máximo o menos (lo menos posible). |
{min,max}? | Haga coincidir el carácter o la subexpresión precedente al menos un mínimo de veces, pero no más de un máximo de veces (lo más cerca posible del mínimo ). |
Observaciones
Codicia
Un cuantificador codicioso siempre intenta repetir el sub-patrón tantas veces como sea posible antes de explorar coincidencias más cortas por retroceso.
En general, un patrón codicioso coincidirá con la cadena más larga posible.
Por defecto, todos los cuantificadores son codiciosos.
pereza
Un cuantificador perezoso (también llamado no codicioso o reacio ) siempre intenta repetir el sub-patrón tan pocas veces como sea posible, antes de explorar coincidencias más largas por expansión.
En general, un patrón perezoso coincidirá con la cadena más corta posible.
Para hacer que los cuantificadores sean perezosos, simplemente agregue ?
al cuantificador existente, por ejemplo, +?
, {0,5}?
.
El concepto de avaricia y pereza solo existe en los motores de retroceso.
La noción de cuantificador codicioso / perezoso solo existe en los motores de regex de retroceso. En los motores de expresiones regulares sin retroceso o los motores de expresiones regulares que cumplen con POSIX, los cuantificadores solo especifican el límite superior y el límite inferior de la repetición, sin especificar cómo encontrar la coincidencia; esos motores siempre coincidirán con la cadena más larga de la izquierda, independientemente.
La codicia contra la pereza
Dada la siguiente entrada:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
Usaremos dos patrones: uno codicioso: A.*Z
, y uno perezoso: A.*?Z
Estos patrones producen las siguientes coincidencias:
-
A.*Z
produce 1 coincidencia:AlazyZgreeedyAlaaazyZ
(ejemplos: Regex101 , Rubular ) -
A.*?Z
produce 2 coincidencias:AlazyZ
yAlaaazyZ
(ejemplos: Regex101 , Rubular )
Primero enfócate en lo que A.*Z
hace. Cuando coincidió con la primera A
, el .*
, Siendo codicioso, luego trata de hacer coincidir tantos .
como sea posible.
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\________________________/
A.* matched, Z can't match
Dado que la Z
no coincide, el motor retrocede, y .*
Debe coincidir con uno menos .
:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\_______________________/
A.* matched, Z can't match
Esto sucede unas cuantas veces más, hasta que finalmente se llega a esto:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\__________________/
A.* matched, Z can now match
Ahora Z
puede coincidir, por lo que el patrón general coincide:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\___________________/
A.*Z matched
Por el contrario, la repetición reacia (perezosa) en A.*?Z
primero coincide con pocas .
como sea posible, y luego tomar más .
según sea necesario. Esto explica por qué encuentra dos coincidencias en la entrada.
Aquí hay una representación visual de lo que los dos patrones combinaron:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\____/l \______/l l = lazy
\_________g_________/ g = greedy
Ejemplo basado en respuesta hecha por poligenelubricantes .
El estándar POSIX no incluye el ?
Operador, muchos motores de expresiones regulares POSIX no tienen una comparación perezosa. Mientras que la refactorización, especialmente con el "mejor truco" , puede ayudar a emparejar, en algunos casos, la única manera de tener un verdadero juego perezoso es usar un motor que lo soporte.
Límites con múltiples coincidencias
Cuando tiene una entrada con límites bien definidos y espera más de una coincidencia en su cadena, tiene dos opciones:
- Usando cuantificadores perezosos;
- Usando una clase de personaje negada.
Considera lo siguiente:
Tienes un motor de plantillas simple, quieres reemplazar subcadenas como $[foo]
donde foo
puede ser cualquier cadena. Desea reemplazar esta subcadena con lo que esté basado en la parte entre []
.
Puedes probar algo como \$\[(.*)\]
, Y luego usar el primer grupo de captura.
El problema con esto es que si tienes una cadena como something $[foo] lalala $[bar] something else
tu pareja será
something $[foo] lalala $[bar] something else
| \______CG1______/|
\_______Match______/
El grupo de captura es foo] lalala $[bar
que puede o no ser válida.
Tienes dos soluciones
Uso de la pereza: en este caso, hacer
*
perezoso es una forma de encontrar las cosas correctas. Así que cambias tu expresión a\$\[(.*?)\]
Usando la clase de caracteres negados:
[^\]]
cambias tu expresión a\$\[([^\]]*)\]
.
En ambas soluciones, el resultado será el mismo:
something $[foo] lalala $[bar] something else
| \_/| | \_/|
\____/ \____/
Con el grupo de captura siendo respectivamente foo
y bar
.
El uso de la clase de caracteres negados reduce el problema del seguimiento y puede ahorrarle mucho tiempo a la CPU cuando se trata de entradas grandes.