2008-09-25 37 views
5

Quiero una expresión regular que pueda coincidir con los comentarios condicionales en una página fuente HTML para que pueda eliminar solo esos. Quiero preservar los comentarios regulares.Regex para eliminar comentarios condicionales

También me gustaría evitar el uso de. *? notación si es posible.

El texto es

foo 

<!--[if IE]> 

<style type="text/css"> 

ul.menu ul li{ 
    font-size: 10px; 
    font-weight:normal; 
    padding-top:0px; 
} 

</style> 

<![endif]--> 

bar 

y quiero eliminar todo en <!--[if IE]> y <![endif]-->

EDIT: Es debido a BeautifulSoup Quiero eliminar estas etiquetas. BeautifulSoup no puede analizar y proporciona una fuente incompleta

EDIT2: [si IE] no es la única condición. Hay muchas más y no tengo ninguna lista de todas las combinaciones posibles.

Edit3: La solución de Vinko Vrsalovic funciona, pero el problema real por la BeautifulSoup no fue a causa de un comentario pícaro dentro de los comentarios condicional. Como

<!--[if lt IE 7.]> 
<script defer type="text/javascript" src="pngfix_253168.js"></script><!--png fix for IE--> 
<![endif]--> 

Fíjese en el comentario <!--png fix for IE-->?

Aunque mi problema se resolvió, me gustaría obtener una solución de expresiones regulares para esto.

+0

Sin. *? no hay ninguno, especialmente si no conoce todas las combinaciones posibles, ¿cómo los atraparía a todos sin *. o similar? Y el modificador no codicioso es necesario en caso de que haya más de un comentario condicional ... –

+0

@Vinko Vrsalovic: puede hacer una búsqueda anticipada para evitar. *? uso: http://www.regular-expressions.info/lookaround.html – Huppie

+0

¿Por qué quieres evitar a los no codiciosos. *? ¿construir? –

Respuesta

0

No use una expresión regular para esto. Se sentirá confundido acerca de los comentarios que contienen etiquetas de apertura y lo que no, y haga lo incorrecto. HTML no es regular, y tratar de modificarlo con una sola expresión regular fallará.

Use un analizador HTML para esto. BeautifulSoup es bueno, fácil, flexible y resistente que es capaz de manejar el HTML del mundo real (lo que significa que no funciona). Con él, puede buscar todos los nodos de comentarios, examinar su contenido (puede usar una expresión regular para que, si lo desea) y eliminarlos si es necesario eliminarlos.

+0

Estrictamente hablando, los comentarios de la codificación no son HTML, sino un lenguaje de macros incrustado, que AFAIK no puede anidarse. Entonces una expresión regular podría funcionar. – JacquesB

1

@Benoit

pequeña corrección (con líneas múltiples activada):

"<!--\[if IE\]>.*?<!\[endif\]-->" 
+0

¿Leyó el mensaje "También me gustaría evitar el uso de la notación. *?" Si es posible "parte? – Huppie

0

Esto funciona en Visual Studio 2005, donde no hay ninguna opción tramo de línea:

\<!--\[if IE\]\>{.|\n}*\<!\[endif\]--\>

5
>>> from BeautifulSoup import BeautifulSoup, Comment 
>>> html = '<html><!--[if IE]> bloo blee<![endif]--></html>' 
>>> soup = BeautifulSoup(html) 
>>> comments = soup.findAll(text=lambda text:isinstance(text, Comment) 
       and text.find('if') != -1) #This is one line, of course 
>>> [comment.extract() for comment in comments] 
[u'[if IE]> bloo blee<![endif]'] 
>>> print soup.prettify() 
<html> 
</html> 
>>>  

python 3 con bf4:

from bs4 import BeautifulSoup, Comment 
html = '<html><!--[if IE]> bloo blee<![endif]--></html>' 
soup = BeautifulSoup(html, "html.parser") 
comments = soup.findAll(text=lambda text:isinstance(text, Comment) 
       and text.find('if') != -1) #This is one line, of course 
[comment.extract() for comment in comments] 
[u'[if IE]> bloo blee<![endif]'] 
print (soup.prettify()) 

Si sus datos se confunden BeautifulSoup, puede fix de antemano o customize el analizador, entre otras soluciones.

EDIT: por su comentario, que acaba de modificar el lambda pasado a findAll como sea necesario (he modificado)

+0

Eso fue útil, pero no quiero perder todas las etiquetas de comentarios. Solo los comentarios css condicional. – cnu

+0

¡esta me ayudó mucho! gracias – sleeplessnerd

2

Esto es lo que necesita:

<!(|--)\[[^\]]+\]>.+?<!\[endif\](|--)> 

Se filtrará todo tipo los comentarios de los condicionales que incluyen:

<!--[if anything]> 
    ... 
<[endif]--> 

y

<![if ! IE 6]> 
    ... 
<![endif]> 

Edit3: La solución de Vinko Vrsalovic funciona, pero el problema real por la BeautifulSoup no fue a causa de un comentario pícaro dentro de los comentarios condicional. Al igual que

Aviso el comentario?

Aunque mi problema se resolvió, me gustaría obtener una solución de expresiones regulares para esto.

¿Qué tal esto:

(<!(|--)\[[^\]]+\]>.*?)(<!--.+?-->)(.*?<!\[endif\](|--)>) 

hacer un reemplazo en esa expresión regular dejando \ 1 \ 4 (o $ 1 $ 4) como el reemplazo.
Sé que tiene. *? y. +? en él, mira mi comentario en esta publicación.

+0

Lamentablemente no pude evitar. +? sintaxis ... – Huppie

+0

Puedes evitar el. +? sintaxis haciendo una referencia directa pero no tengo mi libro de expresiones regulares para la sintaxis exacta: P – Huppie

1

simplemente me quedo con:

import re 

html = """fjlk<wb>dsqfjqdsmlkf fdsijfmldsqjfl fjdslmfkqsjf<---- fdjslmjkqfs---><!--[if lt IE 7.]>\ 
<script defer type="text/javascript" src="pngfix_253168.js"></script><!--png fix for IE-->\ 
<![endif]-->fjlk<wb>dsqfjqdsmlkf fdsijfmldsqjfl fjdslmfkqsjf<---- fdjslmjkqfs--->""" 

# here the black magic occurs (whithout '.') 
clean_html = ''.join(re.split(r'<!--\[[^¤]+?endif]-->', html)) 

print clean_html 

'fjlk<wb>dsqfjqdsmlkf fdsijfmldsqjfl fjdslmfkqsjf<---- fdjslmjkqfs--->fjlk<wb>dsqfjqdsmlkf fdsijfmldsqjfl fjdslmfkqsjf<---- fdjslmjkqfs--->' 

N.B: [^ ¤] coincidirá con cualquier carbón que no es '¤'. Esto es realmente útil ya que es muy rápido y este carácter se puede encontrar en cualquier teclado. Pero el truco es que es muy difícil escribir (nadie lo tipeará por error) y nadie lo usa: es un truco de dinero genérico.

Si usted no se siente como el uso de ¤, sin embargo, se puede utilizar CHR (7) para generar el char "sistema de campana", cosa que está no imprimible y no puede ser encontrado en una página web ;-)

+2

¿Alguna vez escuchó sobre Noruega? http://en.wikipedia.org/wiki/Sm%C3%B8rrebr%C3%B8d – Gregor

+1

Gracias por notar el error tipográfico. Obviamente quise decir ¤, el signo de moneda genérico, y no ø, que es una letra común. –

1

Como yo lo veo, solo tiene que preocuparse por comentarios ocultos (los que comienzan con <!--), y no es necesario que coincida con nada más que la palabra if y el espacio que le sigue. Esto debería hacer lo que quiere:

"<!--\[if\s(?:[^<]+|<(?!!\[endif\]-->))*<!\[endif\]-->" 

Ese desorden en el medio es para satisfacer su deseo de no utilizar .*?, pero realmente no creo que vale la pena el esfuerzo. El enfoque .*? debería funcionar bien si compila la expresión regular con el indicador Re.S establecido o lo ajusta en (?s:...). Por ejemplo:

"(?s:<!--\[if\s.*?<!\[endif\]-->)" 
Cuestiones relacionadas