Cuantificadores codiciosos versus reacios vs. posesivos

357

Encontré este excelente tutorial sobre expresiones regulares y aunque intuitivamente entiendo lo que hacen los cuantificadores "codiciosos", "reacios" y "posesivos", parece que hay un serio vacío en mi comprensión.

Específicamente, en el siguiente ejemplo:

Enter your regex: .*foo  // greedy quantifier
Enter input string to search: xfooxxxxxxfoo
I found the text "xfooxxxxxxfoo" starting at index 0 and ending at index 13.

Enter your regex: .*?foo  // reluctant quantifier
Enter input string to search: xfooxxxxxxfoo
I found the text "xfoo" starting at index 0 and ending at index 4.
I found the text "xxxxxxfoo" starting at index 4 and ending at index 13.

Enter your regex: .*+foo // possessive quantifier
Enter input string to search: xfooxxxxxxfoo
No match found.

La explicación menciona comer toda la cadena de entrada, cartas sido consumidos , coincidencias de dar marcha atrás , la aparición más a la derecha de "foo" ha sido regurgitado , etc.

Desafortunadamente, a pesar de las bonitas metáforas, todavía no entiendo qué come quién ... ¿Conoces otro tutorial que explique (concisamente) cómo funcionan los motores de expresiones regulares?

Alternativamente, si alguien puede explicar en una frase algo diferente el siguiente párrafo, eso sería muy apreciado:

El primer ejemplo usa el cuantificador codicioso. * Para encontrar "cualquier cosa", cero o más veces, seguido de las letras "f" "o" "o". Debido a que el cuantificador es codicioso, la porción. * De la expresión primero se come toda la cadena de entrada. En este punto, la expresión general no puede tener éxito, porque las últimas tres letras ("f" "o" "o") ya han sido consumidas (¿ por quién? ). Entonces, el marcador retrocede lentamente (¿ de derecha a izquierda? ) Una letra a la vez hasta que se regurgita la aparición más a la derecha de "foo" ( ¿qué significa esto? ), Momento en el que la coincidencia tiene éxito y la búsqueda termina.

Sin embargo, el segundo ejemplo es reacio, por lo que comienza consumiendo (¿ por quién? ) "Nada". Debido a que "foo" no aparece al comienzo de la cadena, se ve obligado a tragar (¿ quién traga?) La primera letra (una "x"), que desencadena la primera coincidencia en 0 y 4. Nuestro arnés de prueba continúa el proceso hasta que la cadena de entrada se agote. Encuentra otro partido a las 4 y 13.

El tercer ejemplo no puede encontrar una coincidencia porque el cuantificador es posesivo. En este caso, toda la cadena de entrada es consumida por. * +, ( ¿Cómo? ) Sin dejar nada para satisfacer el "foo" al final de la expresión. Use un cuantificador posesivo para situaciones en las que desea aprovechar todo sin retroceder ( ¿qué significa retroceder? ); superará al cuantificador codicioso equivalente en los casos en que la coincidencia no se encuentre de inmediato.

Novato Regex
fuente
22
Maximal cuantificadores les gusta *, +y ?son codiciosos. Mínimas cuantificadores les gusta *?, +?y ??son perezosos. Posesivos cuantificadores les gusta *+, ++y ?+son pegajosos.
tchrist
66
Esta pregunta se ha agregado a las Preguntas frecuentes sobre la expresión regular de desbordamiento de pila , en "Cuantificadores> Más sobre las diferencias ...".
aliteralmind
De interés: Los Tutoriales de Java ™ - Diferencias entre cuantificadores codiciosos, reacios y posesivos - Desplácese hacia abajo para ver la sección.
Guy Coder

Respuestas:

495

Lo intentaré.

Un cuantificador codicioso primero coincide tanto como sea posible. Entonces, .*coincide con toda la cadena. Luego, el emparejador intenta hacer coincidir lo fsiguiente, pero no quedan caracteres. Por lo tanto, "retrocede", haciendo que el cuantificador codicioso coincida con un carácter menos (dejando la "o" al final de la cadena sin igualar). Eso todavía no coincide fcon la expresión regular, por lo que retrocede un paso más, haciendo que el cuantificador codicioso vuelva a coincidir con un carácter menos (dejando el "oo" al final de la cadena sin igualar). Eso todavía no coincide con el fen la expresión regular, por lo que retrocede un paso más (dejando el "foo" al final de la cadena sin igual). Ahora, el emparejador finalmente coincide con el fen la expresión regular,ootambién son compatibles ¡Éxito!

Un cuantificador renuente o "no codicioso" primero coincide lo menos posible. Por lo tanto .*, no coincide con nada al principio, dejando toda la cadena sin igual. Luego, el emparejador intenta hacer coincidir lo fsiguiente, pero la parte no coincidente de la cadena comienza con "x", por lo que no funciona. Entonces el emparejador retrocede, haciendo que el cuantificador no codicioso coincida con un personaje más (ahora coincide con la "x", dejando "fooxxxxxxfoo" sin igual). Luego intenta hacer coincidir el f, que tiene éxito, y el oy el siguiente oen la coincidencia de expresiones regulares también. ¡Éxito!

En su ejemplo, comienza el proceso nuevamente con la parte restante no coincidente de la cadena, "xxxxxxfoo", siguiendo el mismo proceso.

Un cuantificador posesivo es como el cuantificador codicioso, pero no da marcha atrás. Por lo tanto, comienza haciendo .*coincidir toda la cadena, sin dejar nada sin igualar. Entonces no queda nada para que coincida con el fen la expresión regular. Como el cuantificador posesivo no retrocede, la coincidencia falla allí.

Anomia
fuente
15
+1 Buena respuesta. Solo agregaría: Ir a leer Mastering Regular Expressions (3rd Edition)
ridgerunner
@Anomie un poco tarde pero, en la parte posesiva, creo que querías decir Así que comienza con .*+ (nota el "+")
RD
3
¿Qué hace exactamente el cuantificador posesivo entonces? si no coincide con esto? (Me refiero a cuál es el punto, si no puedes tener personajes después)
relipse el
44
@relipse: Lo usarías en una situación en la que sabes que retroceder no ayudará, probablemente no con .*+eso coincide con todo. Por ejemplo, si tiene un patrón [xyz]*foo, no hay forma de que el retroceso de las x, y y z coincidentes con el [xyz]*bit permita que el siguiente foobit coincida, por lo que puede acelerar las cosas haciéndolo posesivo.
Anomie
44
@moodboom, hay cero casos (hechos matemáticos) en los que los cuantificadores posesivos producirán una coincidencia que no será producida por simples cuantificadores codiciosos. Hay casos ocasionales donde producirán una no coincidencia cuando cuantificadores codiciosos producirían una coincidencia. Para TODOS los demás casos (donde los codiciosos y los posesivos producen los mismos resultados), los cuantificadores posesivos brindan una ganancia de rendimiento.
Comodín
49

Es solo el resultado de mi práctica visualizar la escena.

Imagen visual

SIslam
fuente
3
Excepto que creo que el último caso, posesivo, no debería tener n pases, solo agarra toda la cadena a la vez.
trata bien tus modificaciones el
@phyzome Creo que está bien ahora?
SIslam 01 de
1
Gracias por la explicación visual :)
Lars Moelleken
En EXPRESSION .*?foo(), ¿no deberían los [f] [o] [o]rectángulos ser amarillos en el 5th pass?
tonix
1
@tonix si! La coloración amarilla debe hacerse para la parte coincidente en la expresión .*?fooy .*+foo.
SIslam
24

No he escuchado los términos exactos 'regurgitar' o 'retroceder' antes; la frase que reemplazaría a estos es "retroceder", pero "regurgitar" parece una frase tan buena como cualquier otra para "el contenido que se había aceptado provisionalmente antes de retroceder".

Lo importante a tener en cuenta sobre la mayoría de los motores de expresiones regulares es que están retrocediendo : aceptarán tentativamente una coincidencia parcial potencial, mientras intentan hacer coincidir todo el contenido de la expresión regular. Si la expresión regular no puede coincidir completamente en el primer intento, entonces el motor de expresión regular retrocederá en una de sus coincidencias. Se tratará a juego *, +, ?, alternancia o {n,m}repetición diferente, y vuelve a intentarlo. (Y sí, este proceso puede llevar mucho tiempo).

El primer ejemplo usa el cuantificador codicioso. * Para encontrar "cualquier cosa", cero o más veces, seguido de las letras "f" "o" "o". Debido a que el cuantificador es codicioso, la porción. * De la expresión primero se come toda la cadena de entrada. En este punto, la expresión general no puede tener éxito, porque las últimas tres letras ("f" "o" "o") ya han sido consumidas (¿ por quién? ).

Las últimas tres letras, f, o, y oya estaban consumidos por la primera .*parte de la regla. Sin embargo, al siguiente elemento en la expresión regular, fno le queda nada en la cadena de entrada. El motor se verá obligado a retroceder en su .*partida inicial e intentar hacer coincidir el personaje menos el último. (Puede ser inteligente y retroceder a todos menos los últimos tres, porque tiene tres términos literales, pero no estoy al tanto de los detalles de implementación en este nivel).

Entonces, el emparejador retrocede lentamente (¿ de derecha a izquierda? ) Una letra a la vez hasta que se regurgita la aparición más a la derecha de "foo" ( ¿qué significa esto? ), En qué

Esto significa que se foohabía incluido tentativamente al hacer coincidir .*. Debido a que ese intento falló, el motor de expresiones regulares intenta aceptar un personaje menos .*. Si hubo una coincidencia exitosa antes de la .*de este ejemplo, entonces el motor probablemente trataría de acortar la .*coincidencia (de derecha a izquierda, como señaló, porque es un calificador codicioso), y si no pudo igualar la totalidad de los insumos, entonces podría ser obligado a volver a evaluar lo que había emparejado antes de la .*en mi ejemplo hipotético.

señalar que la coincidencia tiene éxito y la búsqueda finaliza.

Sin embargo, el segundo ejemplo es reacio, por lo que comienza consumiendo primero (¿ por quién? ) "Nada". Porque "foo"

La nada inicial es consumida por .?*, lo que consumirá la menor cantidad posible de cualquier cosa que permita que el resto de la expresión regular coincida.

no aparece al comienzo de la cadena, se ve obligado a tragar (¿ quién traga?)

Nuevamente, .?*consume el primer carácter, después de retroceder en la falla inicial para hacer coincidir la expresión regular completa con la coincidencia más corta posible. (En este caso, el motor regex está extendiendo el partido .*?de izquierda a derecha, porque .*?es reacio).

primera letra (una "x"), que activa la primera coincidencia en 0 y 4. Nuestro arnés de prueba continúa el proceso hasta que se agota la cadena de entrada. Encuentra otro partido a las 4 y 13.

El tercer ejemplo no puede encontrar una coincidencia porque el cuantificador es posesivo. En este caso, toda la cadena de entrada es consumida por. * +, ( ¿Cómo? )

A .*+consumirá tanto como sea posible y no retrocederá para encontrar nuevas coincidencias cuando la expresión regular en su conjunto no pueda encontrar una coincidencia. Debido a la forma posesiva no realiza la marcha atrás, es probable que no vea con muchos usos .*+, sino más bien con las clases de caracteres o restricciones similares: account: [[:digit:]]*+ phone: [[:digit:]]*+.

Esto puede acelerar drásticamente la coincidencia de expresiones regulares, porque le está diciendo al motor de expresiones regulares que nunca debe retroceder sobre coincidencias potenciales si una entrada no coincide. (Si tuviera que escribir todo el código coincidente a mano, esto sería similar a no usar nunca putc(3)para 'retroceder' un carácter de entrada. Sería muy similar al código ingenuo que se podría escribir en un primer intento. Excepto que los motores regex son mucho mejor que un solo carácter de retroceso, pueden rebobinar todo el retroceso a cero e intentar de nuevo. :)

Pero más que posibles aceleraciones, esto también puede permitirle escribir expresiones regulares que coincidan exactamente con lo que necesita. Tengo problemas para encontrar un ejemplo fácil :) pero escribir una expresión regular usando cuantificadores posesivos frente a codiciosos puede darte diferentes coincidencias, y uno u otro puede ser más apropiado.

sin dejar nada para satisfacer al "tonto" al final de la expresión. Use un cuantificador posesivo para situaciones en las que desea aprovechar todo sin retroceder ( ¿qué significa retroceder? ); superará

"Retroceder" en este contexto significa "retroceder": descartar una coincidencia parcial tentativa para intentar otra coincidencia parcial, que puede o no tener éxito.

el cuantificador codicioso equivalente en los casos en que la coincidencia no se encuentra de inmediato.

sarnold
fuente
2
Sospecho que nunca hay un caso en el que un cuantificador posesivo coincida con algo que un cuantificador codicioso no. Creo que lo siguiente lo demuestra: un cuantificador codicioso siempre coincide tanto como sea posible, luego retrocede si no puede encontrar una coincidencia. Un cuantificador posesivo coincide tanto como sea posible, luego se cierra si no puede encontrar una coincidencia. Entonces, puede haber algo con lo que un cuantificador codicioso coincida que un cuantificador posesivo no lo hará, pero no al revés, porque ambos buscan el "árbol" en la misma secuencia, el cuantificador posesivo simplemente se rinde más fácilmente. ;)
Comodín
2
Confirmado: "Para eso están los grupos atómicos y los cuantificadores posesivos: eficiencia al no permitir el retroceso". de regular-expressions.info Entonces, la afirmación en esta respuesta "Pero más que posibles aceleraciones, esto también puede permitirle escribir expresiones regulares que coincidan exactamente con lo que necesita". en realidad no es del todo exacto.
Comodín
1
@Wildcard, gracias por los comentarios; eso puede explicar por qué tuve problemas para encontrar un ejemplo. Jeje.
sarnold
19

http://swtch.com/~rsc/regexp/regexp1.html

No estoy seguro de que esa sea la mejor explicación en Internet, pero está razonablemente bien escrita y adecuadamente detallada, y sigo volviendo a ella. Quizás quieras revisarlo.

Si desea un nivel más alto (explicación menos detallada), para expresiones regulares simples como la que está viendo, un motor de expresión regular funciona al retroceder. Básicamente, elige ("come") una sección de la cadena e intenta hacer coincidir la expresión regular con esa sección. Si coincide, genial. Si no, el motor altera su elección de la sección de la cadena e intenta hacer coincidir la expresión regular contra esa sección, y así sucesivamente, hasta que se pruebe todas las opciones posibles.

Este proceso se usa de forma recursiva: en su intento de hacer coincidir una cadena con una expresión regular dada, el motor dividirá la expresión regular en partes y aplicará el algoritmo a cada pieza individualmente.

La diferencia entre los cuantificadores codiciosos, renuentes y posesivos entra cuando el motor está haciendo la elección de con qué parte de la cadena tratar de hacer coincidir, y cómo modificar esa elección si no funciona la primera vez. Las reglas son las siguientes:

  • Un cuantificador codicioso le dice al motor que comience con toda la cadena (o al menos, todo lo que no ha sido igualado por partes anteriores de la expresión regular) y verifique si coincide con la expresión regular. Si es así, genial; el motor puede continuar con el resto de la expresión regular. Si no, lo intenta nuevamente, pero recorta un carácter (el último) de la sección de la cadena que se va a verificar. Si eso no funciona, recorta a otro personaje, etc. Por lo tanto, un cuantificador codicioso verifica posibles coincidencias en orden de mayor a menor.

  • Un cuantificador renuente le dice al motor que comience con la pieza más corta posible de la cadena. Si coincide, el motor puede continuar; de lo contrario, agrega un carácter a la sección de la cadena que se verifica y lo intenta, y así sucesivamente hasta que encuentre una coincidencia o se haya agotado toda la cadena. Por lo tanto, un cuantificador reacio verifica posibles coincidencias en orden de menor a mayor.

  • Un cuantificador posesivo es como un cuantificador codicioso en el primer intento: le dice al motor que comience comprobando toda la cadena. La diferencia es que si no funciona, el cuantificador posesivo informa que la coincidencia falló en ese momento. El motor no cambia la sección de la cadena que se está mirando, y no hace más intentos.

Esta es la razón por la cual la coincidencia del cuantificador posesivo falla en su ejemplo: .*+se compara con la cadena completa, que coincide, pero luego el motor continúa buscando caracteres adicionales foodespués de eso, pero por supuesto no los encuentra, porque usted Ya estás al final de la cadena. Si se tratara de un cuantificador codicioso, retrocedería e intentaría hacer la .*única coincidencia hasta el penúltimo personaje, luego hasta el penúltimo carácter, luego hasta el penúltimo carácter, lo cual tiene éxito porque solo entonces es hay una fooizquierda después de que el .*ha "comido" la parte anterior de la cadena.

David Z
fuente
1
Esa es una excelente fuente. Me encantan los diagramas de máquinas de estado. :)
Regex Rookie
@Regex Rookie: me alegra que te guste :) Sin embargo, después de revisar ese sitio, creo que debería dejar en claro que su propósito es promover una implementación alternativa de un motor de expresión regular. El algoritmo de retroceso I (parcialmente) y otras respuestas describen es el camino lento ; Es un algoritmo completamente separado de la idea de NFA / DFA descrita en la página web. Retroceder es simplemente más fácil de entender, por eso es como las expresiones regulares generalmente se explican a los principiantes.
David Z
@David Zaslavsky: Buena explicación. Sus comentarios entre paréntesis en "Un cuantificador codicioso le dice al motor que comience con la cadena completa (o al menos, todo lo que no ha sido emparejado por las partes anteriores de la expresión regular)" son importantes. Se aplican también a cuantificadores reacios y posesivos. Esto hace que su explicación sea compatible con lo que sucede cuando cambiamos nuestros patrones de ejemplo de (". * Foo"; ". *? Foo"; y ". * + Foo") a ("foo. *"; "Foo. *? "; y" foo. * + ").
John Bentley
En realidad, xfooxxxxxxfoo coincide. * Foo en la expresión normal (significado informático) de la expresión regular. El NFA sería un estado en el que se repite entre sí con cualquier personaje y luego puede saltar a foo. El DFA sería una traducción directa de ese NFA. Se puede hacer en 8 estados.
user4951
@ JimThio sí, porque ese no es un cuantificador posesivo.
David Z
13

Aquí está mi opinión usando las posiciones de Celda e Índice (Vea el diagrama aquí para distinguir una Celda de un Índice).

Codicioso: coincide tanto como sea posible con el cuantificador codicioso y la expresión regular completa. Si no hay coincidencia, retroceda en el cuantificador codicioso.

Cadena de entrada: xfooxxxxxxfoo
Regex:. * Foo

El Regex anterior tiene dos partes:
(i) '. *' Y
(ii) 'foo'

Cada uno de los pasos a continuación analizará las dos partes. Los comentarios adicionales para una coincidencia con 'Pasar' o 'Fallar' se explican entre llaves.

Paso 1:
(i). * = Xfooxxxxxxfoo - PASS ('. *' Es un cuantificador codicioso y utilizará toda la cadena de entrada)
(ii) foo = No queda ningún carácter que coincida después del índice 13 - Falló la
coincidencia FAIL .

Paso 2:
(i). * = Xfooxxxxxxfo - PASS (Retroceso en el cuantificador codicioso '. *')
(Ii) foo = o - FAIL
Match fallido.

Paso 3:
(i). * = Xfooxxxxxxf - PASS (Retroceso en el cuantificador codicioso '. *')
(Ii) foo = oo - FAIL
Match falló.

Paso 4:
(i). * = Xfooxxxxxx - PASS (Retroceso en el cuantificador codicioso '. *')
(Ii) foo = foo - PASS
Report Match

Resultado: 1 coincidencia (es)
Encontré el texto "xfooxxxxxxfoo" comenzando en el índice 0 y terminando en el índice 13.

Reacio: haga coincidir lo menos posible con el cuantificador de reacios y haga coincidir la expresión regular completa. Si no hay coincidencia, agregue caracteres al cuantificador renuente.

Cadena de entrada: xfooxxxxxxfoo
Regex:. *? Foo

La expresión regular anterior tiene dos partes:
(i) '. *?' y
(ii) 'foo'

Paso 1:.
*? = '' (en blanco) - PASAR (Hacer coincidir lo menos posible con el cuantificador reacio '. *?'. El índice 0 que tiene '' es una coincidencia.)
foo = xfo - FALLO (Celda 0,1,2 - es decir, índice entre 0 y 3)
Partido fallido.

Paso 2:.
*? = X - PASS (Agrega personajes para el cuantificador reacios celular 0 tener 'x' es un partido '*.?'..)
Foo foo = - PASS
DEL PARTIDO

Paso 3:.
*? = '' (en blanco) - PASAR (Coincidir lo menos posible con el cuantificador reacio '. *?'. El índice 4 que tiene '' es una coincidencia.)
foo = xxx - FALLO (Celda 4,5,6 - es decir, índice entre 4 y 7)
Partido fallido.

Paso 4:.
*? = x - PASAR (Agregar caracteres al cuantificador renuente '. *?'. Celda 4.)
foo = xxx - FALLO (Celda 5,6,7 - es decir, índice entre 5 y 8)
Falló la coincidencia.

Paso 5:.
*? = xx - PASAR (Agregar caracteres al cuantificador reacio '. *?'. Celdas 4 a 5.)
foo = xxx - FALLO (Celda 6,7,8 - es decir, índice entre 6 y 9) La
coincidencia falló.

Paso 6:.
*? = xxx - PASAR (Agregar caracteres al cuantificador renuente '. *?'. Celdas 4 a 6.)
foo = xxx - FALLO (Celda 7,8,9 - es decir, índice entre 7 y 10) La
coincidencia falló.

Paso 7:.
*? = xxxx - PASAR (Agregar caracteres al cuantificador renuente '. *?'. Celda 4 a 7.)
foo = xxf - FALLO (Celda 8,9,10 - es decir, índice entre 8 y 11)
Falló la coincidencia.

Paso 8:.
*? = xxxxx - PASAR (Agregar caracteres al cuantificador renuente '. *?'. Celda 4 a 8.)
foo = xfo - FALLO (Celda 9,10,11 - es decir, índice entre 9 y 12) La
coincidencia falló.

Paso 9:.
*? = xxxxxx - PASS (Agregue caracteres al cuantificador reacio '. *?'. Celda 4 a 9.)
foo = foo - PASS (Celda 10,11,12 - es decir, índice entre 10 y 13)
Informe MATCH

Paso 10:.
*? = '' (Blanco) - PASS (Partido lo menos posible a la cuantificador renuente '*' Índice 13 está en blanco.?..)
Foo = n carácter a la izquierda para que coincida - FAIL (No hay nada después de índice 13 para que coincida)
Partido ha fallado.

Resultado: 2 coincidencias
Encontré el texto "xfoo" comenzando en el índice 0 y terminando en el índice 4.
Encontré el texto "xxxxxxfoo" comenzando en el índice 4 y terminando en el índice 13.

Posesivo: unir lo más posible al cuantificador posesivo y unir la expresión regular completa. NO retroceda.

Cadena de entrada: xfooxxxxxxfoo
Regex:. * + Foo

La expresión regular anterior tiene dos partes: '. * +' Y 'foo'.

Paso 1:.
* + = Xfooxxxxxxfoo - PASAR (Coincidir tanto como sea posible con el cuantificador posesivo '. *')
Foo = No queda ningún carácter para que coincida - FALLO (Nada que coincida después del índice 13)
Falló la coincidencia.

Nota: el retroceso no está permitido.

Resultado: 0 partido (s)

raka
fuente
1

Codicioso: "coincide con la secuencia de personajes más larga posible"

Reacio: "coincide con la secuencia de caracteres más corta posible"

Posesivo: Esto es un poco extraño ya que NO (en contraste con la avaricia y la renuencia) intenta encontrar una coincidencia para toda la expresión regular.

Por cierto: ninguna implementación de igualador de patrones de expresiones regulares utilizará el retroceso. Todos los patrones de coincidencia de la vida real son extremadamente rápidos, ¡casi independientes de la complejidad de la expresión regular!

Tilo Koerbs
fuente
Hasta donde yo sé, la mayoría de las implementaciones de uso general ahora están repletas de características tan completas que se hizo imposible no usar el rastreo. Entonces, en teoría, deberían ser extremadamente (exponencialmente) lentos en algunos casos. Pero para la mayoría de esos casos hay optimizaciones especiales integradas en el patrón de coincidencia.
Robert
0

La codificación codiciosa implica la coincidencia de patrones utilizando todos los caracteres no validados restantes de una cadena durante una iteración. Los caracteres no validados comienzan en la secuencia activa . Cada vez que no se produce una coincidencia, el personaje al final se pone en cuarentena y la verificación se realiza nuevamente.

Cuando la secuencia activa solo satisface las condiciones principales del patrón regex, se intenta validar las condiciones restantes contra la cuarentena. Si esta validación es exitosa, los caracteres coincidentes en la cuarentena se validan y los caracteres no coincidentes residuales permanecen sin validar y se usarán cuando el proceso comience nuevamente en la próxima iteración.

El flujo de caracteres es de la secuencia activa a la cuarentena. El comportamiento resultante es que la mayor parte de la secuencia original se incluye en una coincidencia como sea posible.

La cuantificación reacia es casi lo mismo que la calificación codiciosa, excepto que el flujo de caracteres es lo contrario, es decir, comienzan en la cuarentena y fluyen hacia la secuencia activa . El comportamiento resultante es que se incluye lo menos posible de la secuencia original en una coincidencia.

La cuantificación posesiva no tiene cuarentena e incluye todo en una secuencia activa fija .

Chad Philip Johnson
fuente