2008-12-14 15 views
12

expresiones regulares siempre he escrito como esteRegex: ¿es perezosa?

<A HREF="([^"]*)" TARGET="_blank">([^<]*)</A> 

pero me acaban de aprender acerca de este lazy thing y que puede escribir como esto

<A HREF="(.*?)" TARGET="_blank">(.*?)</A> 

¿hay alguna desventaja de utilizar este segundo enfoque? La expresión regular es definitivamente más compacta (incluso SO lo analiza mejor).

Editar: Aquí hay dos mejores respuestas, que señalan dos diferencias importantes entre las expresiones. La respuesta de ysth apunta a una debilidad en el no codicioso/flojo, en el que el hipervínculo podría incluir otros atributos de la etiqueta A (definitivamente no es bueno). Rob Kennedy señala una debilidad en el ejemplo codicioso, en que los textos de anclaje no pueden incluir otras etiquetas (definitivamente no está bien, porque tampoco captaría todo el texto de anclaje) ... así que la respuesta es que, las expresiones regulares son lo que son, las soluciones perezosas y no perezosas que parecen iguales probablemente no son semánticamente equivalentes.

Editar: La tercera mejor respuesta es por Alan M sobre la velocidad relativa de las expresiones. Por el momento, marcaré su respuesta como mejor para que la gente le dé más puntos :)

+2

¡LOL! Gracias por el impulso. –

+0

Claro, pero aparentemente una vez que la pregunta envejece un poco ya nadie lo ama. –

+0

Si puede cambiar la respuesta aceptada, siéntase libre de hacerlo. Mi respuesta realmente no respondió la pregunta, solo me explicó las otras respuestas. –

Respuesta

12

Otro aspecto a considerar es el tiempo que el texto de destino, y cómo gran parte de ella va a ser igualado por el sub-expresión cuantificada. Por ejemplo, si estuviera tratando de igualar todo el elemento < BODY> en un documento HTML grande, que podría estar tentado a usar esta expresión regular:

/<BODY>.*?<\/BODY>/is 

Pero eso va a hacer una gran cantidad de trabajo innecesario, igualando un personaje a la vez mientras se hace un lookahead negativo antes de cada uno. Usted sabe que la etiqueta </BODY> va a estar muy cerca del final del documento, por lo que lo más inteligente es usar un cuantitier codicioso normal; deje que absorba todo el resto del documento y luego deshaga los pocos caracteres necesarios para que coincida con la etiqueta final.

En la mayoría de los casos, no notará ninguna diferencia de velocidad entre los cuantificadores codiciosos y reacios, pero es algo a tener en cuenta. La razón principal por la que debe ser juicioso en el uso de cuantificadores reacios es la señalada por los otros: pueden hacerlo de mala gana, pero coincidirán más de lo que usted quiera si eso es lo que se necesita para lograr un total partido.

1

"lazy" es la palabra incorrecta aquí. Quieres decir no codicioso en lugar de codicioso. No hay desventaja en su uso, que yo sepa. Pero en su caso especial, tampoco debería ser más eficiente.

+0

Gracias por su respuesta. Estos muchachos http://www.regular-expressions.info/repeat.html se refieren a perezosos o codiciosos, que admito que tienen menos sentido que codiciosos y no codiciosos. –

+2

Te puede interesar saber que "esos tipos" en realidad es Jan Goyvaerts, un miembro de SO. ;) –

+0

Sí, realmente no me puedo quejar de la calidad de SO memeber's. La última vez que utilicé un foro técnico con este nivel de respuestas fue el foro xSLT, y un famoso gurú llamado David Carlile (algo así) respondió la mayoría de las preguntas personalmente. –

3

No se trata de algo mejor o peor. El término que he visto más es codicioso vs. no codicioso, pero como quiera que sea, hacen dos cosas diferentes. Desea usar el correcto para la tarea. Es decir. desactive la opción codiciosa cuando no desee capturar varias coincidencias en una línea.

1

No codicioso es mejor, ¿verdad? Funciona hacia adelante, verificando una coincidencia cada vez y deteniéndose cuando encuentra una, mientras que el cierre de kleene normal (*) funciona al revés coincidiendo con el resto de la entrada y eliminando las cosas hasta que encuentra una coincidencia.

Al final, hacen cosas diferentes, pero creo que los no codiciosos superan a los codiciosos. Tenga en cuenta que no he probado esto, pero ahora tengo curiosidad.

+1

apuesta es dependiente de la implementación. ¡Gracias por tu respuesta! –

7

Tenga en cuenta que sus ejemplos no son equivalentes. Su primera expresión regular no seleccionará ningún enlace que contenga otras etiquetas, como img o b. La segunda expresión regular lo hará, y espero que eso sea probablemente lo que querías de todos modos.

Además de la diferencia de significado, la única desventaja que puedo pensar es que el soporte para modificadores no codiciosos no es tan frecuente como lo es la negación de clase de carácter. It's more widely supported than I thought, before I checked, but notably absent from the list is GNU Grep. Si los evaluadores de expresiones regulares que está utilizando lo admiten, continúe y utilícelo.

+0

Hola Rob, es verdad, quiero NADA que pueda ir entre las etiquetas A. Si mi evaluador de expresiones regex lo admite ... wow, ni siquiera sabía que no podría. Tendré que verificar (estoy en AS3) y editaré la pregunta con eso. –

8

La clase de personaje complementado define más rigurosamente lo que quiere que coincida, así que cuando pueda, lo usaría.

La expresión regular no codicioso coincidirá con cosas que probablemente no desee, tales como:.

<A HREF="foo" NAME="foo" TARGET="_blank">foo</A> 

donde su primera *?partidos

foo" NAME="foo 
+0

No recibo su última observación. En su opinión, ¿qué se compararía aquí y por qué sería diferente de lo que queremos? –

+0

¿No es el primero. *? unir el menor número posible de caracteres antes de hacer coincidir la comilla doble, por lo tanto, solo coincide con foo? – Kenny

+0

ysth: Ahora veo tu punto, es decir, que los argumentos se reordenan. –

Cuestiones relacionadas