2010-11-25 12 views
5

Código:

str = '<br><br />A<br />B' 
print(re.sub(r'<br.*?>\w$', '', str)) 

Se espera que regrese <br><br />A, pero devuelve una cadena vacía ''!

¿Alguna sugerencia?

+2

Por favor, nunca use 'str' como nombre de variable. –

+0

Gracias a su sugerencia. –

+1

Uh ... oye ... no estás analizando HTML con expresiones regulares, ¿o sí? – detly

Respuesta

6

La codicia funciona de izquierda a derecha, pero no de otra manera. Básicamente significa "no coinciden a menos que no coincida". Esto es lo que está pasando:

  1. El motor de expresiones regulares coincide con <br al comienzo de la cadena.
  2. .*? se ignora por ahora, es flojo.
  3. Intente hacer coincidir >, y tiene éxito.
  4. Intente hacer coincidir \w y falla. Ahora es interesante: el motor comienza a retroceder y ve la regla .*?. En este caso, . puede coincidir con el primer >, por lo que aún hay esperanzas de que coincida.
  5. Esto sigue sucediendo hasta que la expresión regular alcanza la barra diagonal. Entonces >\w puede coincidir, pero $ falla. Una vez más, el motor vuelve a la regla perezoso .*, y mantiene a juego, hasta que coincida con <br><br />A<br />B

Afortunadamente, hay una solución fácil: Mediante la sustitución de <br[^>]*>\w$ no lo hace permiten juego fuera de sus etiquetas, por lo debería reemplazar la última ocurrencia.
Estrictamente hablando, esto no funciona bien para HTML, porque los atributos de etiqueta pueden contener > caracteres, pero supongo que es solo un ejemplo.

1

La falta de codicia no comenzará más tarde de esa manera. Coincide con el primer <br y no coincidirá con ganas el resto, que en realidad debe ir al final de la cadena porque especifica $.

Para que funcione de la manera que quería, utilice

/<br[^<]*?>\w$/ 

pero por lo general, no se recomienda el uso de expresiones regulares para analizar HTML, como el valor de algún atributo puede tener < o > en ella.

Cuestiones relacionadas