solo regulares regular probar numeros letras expresiones expresion especiales espacios espacio ejemplos caracteres blanco alfanumerico regex regex-greedy

regex - probar - expresiones regulares java



Cuál es la diferencia entre.*? y.*expresiones regulares? (3)

Estoy tratando de dividir una cadena en dos partes usando expresiones regulares. La cadena está formateada de la siguiente manera:

text to extract<number>

He estado usando (.*?)< Y <(.*?)> Que funcionan bien, pero después de leer un poco sobre Regex, acabo de empezar a preguntarme por qué necesito el ? en las expresiones. Solo lo hice así después de encontrarlos en este sitio, así que no estoy exactamente seguro de cuál es la diferencia.


En codiciosos vs no codiciosos

La repetición en expresiones regulares por defecto es codiciosa : intentan coincidir tantas repeticiones como sea posible, y cuando esto no funciona y tienen que dar marcha atrás, intentan emparejar un representante menos a la vez, hasta que coincida un patrón completo. encontró. Como resultado, cuando finalmente ocurre un partido, una repetición codiciosa coincidirá con tantas repeticiones como sea posible.

El ? como un cuantificador de repetición cambia este comportamiento a no codicioso , también llamado reacio ( en, por ejemplo, Java ) (y, a veces "perezoso"). Por el contrario, esta repetición primero intentará hacer coincidir el menor número de repeticiones posible, y cuando esto no funciona y tienen que dar marcha atrás, comienzan a emparejar un reptil más por vez. Como resultado, cuando finalmente se produce una coincidencia, una repetición reacia coincidiría con la menor cantidad posible de representantes.

Referencias

Ejemplo 1: De la A a la Z

Comparemos estos dos patrones: A.*Z y A.*Z A.*?Z

Dada la siguiente entrada:

eeeAiiZuuuuAoooZeeee

Los patrones producen las siguientes coincidencias:

Primero, concéntrese en lo que hace A.*Z Cuando coincidía con la primera A , el .* , Siendo codicioso, primero intenta igualar a tantos . como sea posible.

eeeAiiZuuuuAoooZeeee /_______________/ A.* matched, Z can''t match

Como la Z no coincide, el motor retrocede, y .* Debe coincidir con uno menos . :

eeeAiiZuuuuAoooZeeee /______________/ A.* matched, Z still can''t match

Esto sucede algunas veces más, hasta que finalmente llegamos a esto:

eeeAiiZuuuuAoooZeeee /__________/ A.* matched, Z can now match

Ahora Z puede coincidir, por lo que el patrón general coincide:

eeeAiiZuuuuAoooZeeee /___________/ A.*Z matched

Por el contrario, la repetición reacia en A.*?Z primero coincide con pocos . 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 coinciden los dos patrones:

eeeAiiZuuuuAoooZeeee /__/r /___/r r = reluctant /____g____/ g = greedy

Ejemplo: una alternativa

En muchas aplicaciones, las dos coincidencias en la entrada anterior son las deseadas, por lo tanto, son reacias .*? se usa en lugar de codicioso .* para evitar el exceso de coincidencia. Para este patrón particular, sin embargo, hay una mejor alternativa, utilizando una clase de caracteres negada.

El patrón A[^Z]*Z también encuentra las mismas dos coincidencias que el patrón A.*?Z para la entrada anterior ( como se ve en ideone.com ). [^Z] es lo que se llama una clase de carácter negada : coincide con todo menos con Z

La principal diferencia entre los dos patrones está en el rendimiento: al ser más estricto, la clase de carácter negada solo puede coincidir de una manera con una entrada determinada. No importa si usa un modificador codicioso o renuente para este patrón. De hecho, en algunos sabores, puedes hacerlo aún mejor y usar lo que se llama cuantificador posesivo, que no se retrasa en absoluto.

Referencias

Ejemplo 2: De A a ZZ

Este ejemplo debe ser ilustrativo: muestra cómo los patrones de clase de carácter codicioso, renuente y negado coinciden de manera diferente dada la misma entrada.

eeAiiZooAuuZZeeeZZfff

Estas son las coincidencias para la entrada anterior:

Aquí hay una representación visual de lo que coinciden:

___n / / n = negated character class eeAiiZooAuuZZeeeZZfff r = reluctant /_________/r / g = greedy /____________/g

Temas relacionados

Estos son enlaces a preguntas y respuestas sobre que cubren algunos temas que pueden ser de su interés.

Una repetición codiciosa puede pasar a otro


Digamos que tienes:

<a></a>

<(.*)> coincidiría con a></a donde como <(.*?)> coincidiría con a . Este último se detiene después del primer partido de > . Comprueba una o 0 coincidencias de .* Seguido de la siguiente expresión.

La primera expresión <(.*)> No se detiene al hacer coincidir los primeros > . Continuará hasta el último partido de > .


Es la diferencia entre cuantificadores codiciosos y no codiciosos.

Considere la entrada 101000000000100 .

Usar 1.*1 , * es codicioso: coincidirá hasta el final y luego retrocede hasta que pueda coincidir con 1 , dejándote con 1010000000001 .
.*? no es codicioso * no coincidirá con nada, pero luego intentará unir los caracteres adicionales hasta que coincida con 1 , eventualmente haciendo coincidir 101 .

Todos los cuantificadores tienen un modo no codicioso:. .*? , .+? , .{2,6}? e incluso .?? .

En su caso, un patrón similar podría ser <([^>]*)> - haciendo coincidir cualquier cosa que no sea un signo mayor que (estrictamente hablando, coincide con cero o más caracteres distintos de > entre-y < y > ).

Vea la Hoja de trucos de Quantifier .