¿Cómo puedo escribir una expresión regular que coincida con no codiciosa? [duplicar]
Necesito ayuda sobre la coincidencia de expresiones regulares con la opción no codiciosa.
El patrón de coincidencia es:
<img\s.*>
El texto a coincidir es:
<html>
<img src="test">
abc
<img
src="a" src='a' a=b>
</html>
Lo pruebo en http://regexpal.com
Esta expresión coincide con todo el texto desde <img
hasta el último >
. Necesito que coincida con el primero encontrado >
después del inicial <img
, por lo que aquí necesitaría obtener dos coincidencias en lugar de la que obtengo.
Probé todas las combinaciones de non-greedy?
, sin éxito.
El no codicioso ?
funciona perfectamente bien. Es solo que necesita seleccionar la opción puntos coincide con todos en los motores de expresiones regulares ( regexpal , el motor que usó, también tiene esta opción) que está probando. Esto se debe a que los motores de expresiones regulares generalmente no coinciden con los saltos de línea cuando usas .
. Debes decirles explícitamente que también deseas hacer coincidir los saltos de línea con.
Por ejemplo,
<img\s.*?>
¡funciona bien!
Consulta los resultados aquí .
Además, lea sobre cómo se comporta el punto en varios tipos de expresiones regulares.
El ?
operando hace que la coincidencia no sea codiciosa. Por ejemplo, .*
es codicioso mientras que .*?
no lo es. Entonces puedes usar algo como <img.*?>
para hacer coincidir toda la etiqueta. O <img[^>]*>
.
Pero recuerde que todo el conjunto de HTML no se puede analizar con expresiones regulares.
Las otras respuestas aquí presuponen que tiene un motor de expresiones regulares que admite coincidencias no codiciosas, que es una extensión introducida en Perl 5 y ampliamente copiada a otros lenguajes modernos; pero de ninguna manera es omnipresente.
Muchos editores y lenguajes más antiguos o más conservadores solo admiten expresiones regulares tradicionales, que no tienen ningún mecanismo para controlar la codicia del operador de repetición *
: siempre coincide con la cadena más larga posible.
El truco entonces es limitar lo que se permite igualar en primer lugar. En lugar de .*
ti pareces estar buscando
[^>]*
que todavía coincide con la mayor cantidad posible de algo ; pero el algo no es simplemente .
"cualquier carácter", sino "cualquier carácter que no lo sea >
".
Dependiendo de su aplicación, es posible que desee o no habilitar una opción para permitir que "cualquier carácter" incluya nuevas líneas.
Incluso si su motor de expresiones regulares admite coincidencias no codiciosas, es mejor explicar con detalle lo que realmente quiere decir. Si esto es lo que quieres decir, probablemente deberías decir esto, en lugar de confiar en coincidencias no codiciosas para (con suerte, probablemente) hacer lo que quiero decir.
Por ejemplo, una expresión regular con un contexto final después del comodín .*?><br/>
saltará sobre cualquier anidado >
hasta que encuentre el contexto final (aquí ><br/>
) incluso si eso requiere abarcar múltiples >
instancias y nuevas líneas si lo permite, donde [^>]*><br/>
(o incluso [^\n>]*><br/>
si tiene para rechazar explícitamente la nueva línea) obviamente no puede y no hará eso.
Por supuesto, esto todavía no es lo que quieres si necesitas lidiar con <img title="quoted string with > in it" src="other attributes"> and perhaps <img title="nested tags">
, pero en ese punto, finalmente deberías dejar de usar expresiones regulares para esto, como te dijimos en primer lugar.