¿Alguien podría explicar estos dos términos de una manera comprensible?
regex
regex-greedy
non-greedy
ajsie
fuente
fuente
Respuestas:
Codicioso consumirá tanto como sea posible. En http://www.regular-expressions.info/repeat.html vemos el ejemplo de intentar hacer coincidir las etiquetas HTML con
<.+>
. Supongamos que tiene lo siguiente:Puede pensar que
<.+>
(.
significa cualquier personaje que no sea de nueva línea y+
significa uno o más ) solo coincidiría con el<em>
y el</em>
, cuando en realidad será muy codicioso, y pasará del primero<
al último>
. Esto significa que coincidirá en<em>Hello World</em>
lugar de lo que quería.Hacerlo perezoso (
<.+?>
) evitará esto. Al agregar el?
después del+
, le decimos que se repita la menor cantidad de veces posible , por lo que lo primero>
que aparece es dónde queremos detener la coincidencia.Te animo a que descargues RegExr , una gran herramienta que te ayudará a explorar expresiones regulares. Lo uso todo el tiempo.
fuente
<[^>]+>
regex101.com/r/lW0cY6/1'Codicioso' significa que coincida la cadena más larga posible
'Perezoso' significa una cadena más corta posible.
Por ejemplo, los codiciosos
h.+l
partidos'hell'
en'hello'
pero los perezososh.+?l
partidos'hel'
.fuente
h.+l
partidos'helol'
en'helolo'
pero los perezososh.+?l
partidos'hel'
.x?
significa quex
es opcional pero+?
es una sintaxis diferente. Significa dejar de cuidar cuando encuentre algo que coincida: coincidencia perezosa.?
significa opcional y+?
significa perezoso. Por\+?
lo tanto, los medios+
son opcionales.Ejemplo:
cadena de prueba: stackoverflow
expresión cod codiciosa :
s.*o
salida: stackoverflo wexpresión reg perezosa :
s.*?o
salida: stacko verflowfuente
re.match('(f)?(.*)', 'food').groups()
conre.match('(f)??(.*)', 'food').groups()
. En el último,(f)??
no coincidirá con la 'f' principal, aunque podría. Por lo tanto, la 'f' coincidirá con el segundo grupo de captura '. *'. Estoy seguro de que puedes construir un ejemplo con '{n}?' también. Es cierto que estos dos se usan muy raramente.Codicioso significa que su expresión coincidirá con el grupo más grande posible, perezoso significa que coincidirá con el grupo más pequeño posible. Para esta cadena:
y esta expresión:
Una coincidencia codiciosa coincidirá con toda la cadena, y una coincidencia perezosa coincidirá solo con la primera
abc
.fuente
Hasta donde yo sé, la mayoría de los motores de expresiones regulares son codiciosos por defecto. Agregar un signo de interrogación al final del cuantificador habilitará la coincidencia diferida.
Como @Andre S mencionó en el comentario.
Consulte el siguiente ejemplo para saber qué es codicioso y qué es perezoso.
El resultado es:
fuente
Tomado de www.regular-expressions.info
Codicia : los cuantificadores codiciosos primero intentan repetir la ficha tantas veces como sea posible, y gradualmente abandona las coincidencias a medida que el motor retrocede para encontrar una coincidencia general.
Pereza : el cuantificador perezoso primero repite el token tantas veces como sea necesario y expande gradualmente la coincidencia a medida que el motor retrocede a través de la expresión regular para encontrar una coincidencia general.
fuente
De expresión regular
fuente
Juego codicioso. El comportamiento predeterminado de las expresiones regulares es ser codicioso. Eso significa que intenta extraer lo más posible hasta que se ajuste a un patrón, incluso cuando una parte más pequeña hubiera sido sintácticamente suficiente.
Ejemplo:
En lugar de coincidir hasta la primera aparición de '>', extrajo la cadena completa. Este es el comportamiento codicioso o "tómalo todo" predeterminado de regex.
La combinación perezosa , por otro lado, "toma lo menos posible". Esto puede realizarse agregando un
?
al final del patrón.Ejemplo:
Si solo desea recuperar la primera coincidencia, utilice el método de búsqueda.
Fuente: Python Regex Ejemplos
fuente
Codicioso significa que consumirá su patrón hasta que no quede ninguno y no pueda buscar más.
Lazy se detendrá tan pronto como encuentre el primer patrón que solicitó.
Un ejemplo común que a menudo encuentro es
\s*-\s*?
una expresión regular.([0-9]{2}\s*-\s*?[0-9]{7})
El primero
\s*
se clasifica como codicioso debido a*
que buscará tantos espacios en blanco como sea posible después de que se encuentren los dígitos y luego busque un carácter de guión "-". Donde como el segundo\s*?
es perezoso debido al presente,*?
significa que se verá el primer carácter de espacio en blanco y se detendrá allí.fuente
Se muestra mejor con el ejemplo. Cuerda.
192.168.1.1
y una expresión regular codiciosa.\b.+\b
Puede pensar que esto le daría el primer octeto, pero en realidad coincide con toda la cadena. ¿Por qué? Porque. + Es codicioso y una coincidencia codiciosa coincide con cada personaje192.168.1.1
hasta que llega al final de la cadena. Esta es la parte importante! Ahora comienza a retroceder un personaje a la vez hasta que encuentre una coincidencia para la tercera ficha (\b
).Si la cadena de un archivo de texto de 4GB y 192.168.1.1 estaba al principio, podría ver fácilmente cómo este retroceso podría causar un problema.
Para hacer una expresión regular no codiciosa (perezosa) ponga un signo de interrogación después de su búsqueda codiciosa, por ejemplo
Lo que sucede ahora es que la ficha 2 (
+?
) encuentra una coincidencia, la expresión regular se mueve a lo largo de un personaje y luego prueba la siguiente ficha (\b
) en lugar de la ficha 2 (+?
). Entonces se arrastra con cautela.fuente
Los cuantificadores codiciosos son como el IRS / ATO: toman tanto como pueden:
Si está allí, vendrán y lo tomarán. Se lo llevarán todo:
Por ejemplo, el IRS coincide con esta expresión regular:
.*
$50,000
- El IRS lo tomará todo. Esos codiciosos.*{4}?
ERSVea aquí para ver un ejemplo: regexr.com/4t27f
Cuantificadores no codiciosos: toman tan poco como pueden
Por otro lado, si solicito un reembolso de impuestos, el IRS de repente se vuelve no codicioso y usan este cuantificador:
(.{2}?)([0-9]*)
en contra de esta expresión:$50,000
el primer grupo no es necesitado y solo coincide$5
, por lo que obtengo un$5
reembolso. El resto lo toma el tío Sam para gastarlo malgastamente.Ver aquí: ejemplo no codicioso .
¿Por qué molestarse?
Se vuelve importante si está tratando de hacer coincidir ciertas partes de una expresión. A veces no quieres igualar todo.
fuente
intenta comprender el siguiente comportamiento:
fuente