2008-09-25 11 views
5

Je veux une regex qui peut correspondre à des commentaires conditionnels dans une page source HTML afin que je puisse supprimer seulement ceux. Je veux préserver les commentaires réguliers.Regex pour supprimer les commentaires conditionnels

Je voudrais également éviter d'utiliser le. *? notation si possible.

Le texte est

foo 

<!--[if IE]> 

<style type="text/css"> 

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

</style> 

<![endif]--> 

bar 

et je veux enlever tout <!--[if IE]> et <![endif]-->

EDIT: Il est à cause de BeautifulSoup je veux supprimer ces balises. BeautifulSoup ne parvient pas à analyser et donne une source incomplète

EDIT2: [si IE] n'est pas la seule condition. Il y en a beaucoup plus et je n'ai pas de liste de toutes les combinaisons possibles.

EDIT3: solution de Vinko Vrsalovic fonctionne, mais le problème réel pourquoi beautifulsoup n'a pas été à cause d'un commentaire voyous dans le commentaire conditionnel. Comme

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

Notez le <!--png fix for IE--> comment?

Bien que mon problème ait été résolu, j'aimerais obtenir une solution regex pour cela.

+0

Sans. *? il n'y en a pas, surtout si vous ne connaissez pas toutes les combinaisons possibles, comment les attraperiez-vous sans un. * ou similaire? Et le modificateur non-gourmand est nécessaire dans le cas où il y a plus d'un commentaire conditionnel ... –

+0

@Vinko Vrsalovic: Vous pouvez faire un lookahead correspondant à prévenir. *? utilisation: http://www.regular-expressions.info/lookaround.html – Huppie

+0

Pourquoi voulez-vous éviter les non-gourmands. *? construction? –

Répondre

0

N'utilisez pas une expression régulière pour cela. Vous serez confus au sujet des commentaires contenant des balises d'ouverture et de ce qui ne l'est pas, et faites la mauvaise chose. HTML n'est pas régulier, et essayer de le modifier avec une seule expression régulière échouera.

Utilisez un analyseur HTML pour cela. BeautifulSoup est un bon, facile, flexible et robuste qui est capable de gérer le HTML réel (signifiant désespérément cassé). Avec lui, vous pouvez simplement rechercher tous les nœuds de commentaire, examiner leur contenu (vous pouvez utiliser une expression régulière pour que, si vous le souhaitez) et les supprimer s'ils doivent être supprimés.

+0

Strictement parlant, les commentaires de codage ne sont pas HTML mais un langage de macro incorporé, qui ne peut pas être imbriqué. Donc, une regex pourrait fonctionner. – JacquesB

1

@Benoit

Petite correction (avec multiligne activé):

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

Avez-vous lu le "Je voudrais aussi éviter d'utiliser la notation. *? Si possible." "part? – Huppie

0

Cela fonctionne dans Visual Studio 2005, où il n'y a pas d'option de portée de la ligne:

\<!--\[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 avec bf4:

Si vos données sont confondues avec BeautifulSoup, vous pouvez le fix auparavant ou customize l'analyseur, parmi d'autres solutions.

EDIT: Par votre commentaire, vous modifiez juste le lambda passé à findAll que vous avez besoin (je l'ai modifié)

+0

Cela a été utile, mais je ne veux pas perdre tous les tags de commentaires. Seuls les commentaires css conditionnels. – cnu

+0

celui-ci m'a beaucoup aidé! merci – sleeplessnerd

2

Voici ce que vous aurez besoin:

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

Il filtrera toutes sortes des commentaires conditionnels dont:

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

et

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

EDIT3: solution de Vinko Vrsalovic fonctionne, mais le problème réel pourquoi beautifulsoup n'a pas été à cause d'un commentaire voyous dans le commentaire conditionnel. Comme

Notez le commentaire?

Bien que mon problème ait été résolu, j'aimerais obtenir une solution regex pour cela.

Que diriez-vous ceci:

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

Est-ce un remplacement sur cette expression régulière laissant \ 1 \ 4 (ou 1 $ 4 $) que le remplacement.
Je sais qu'il a. *? et. +? dedans, voir mon commentaire sur ce post.

+0

Malheureusement, je ne pouvais pas éviter. +? syntaxe si ... – Huppie

+0

Vous pouvez éviter le. +? syntaxe en faisant une référence avant mais je n'ai pas mon livre regex avec moi pour la syntaxe exacte: P – Huppie

1

Je voudrais simplement aller avec:

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.: [^ ¤] correspond à tout omble chevalier qui ne sont pas '¤'. Ceci est vraiment utile car il est rapide comme l'éclair et ce caractère peut être trouvé sur n'importe quel clavier. Mais l'astuce est qu'il est vraiment difficile à taper (personne ne le tapera par erreur) et personne ne l'utilise: c'est un char générique.

Si vous ne vous sentez pas comme l'utilisation de ¤, cependant, vous pouvez utiliser chr (7) pour générer le char « cloche système », Wich est non imprimable et ne se trouve pas dans une page web ;-)

+2

Jamais entendu parler de la Norvège? http://en.wikipedia.org/wiki/Sm%C3%B8rrebr%C3%B8d – Gregor

+1

Merci d'avoir noté la faute de frappe. Je voulais dire ¤, le signe monétaire générique, et non ø, qui est une lettre commune. –

1

Comme je le vois, vous avez seulement besoin de s'inquiéter de downlevel-hidden commentaires (ceux qui commencent par <!--), et vous n'avez pas besoin de faire correspondre autre chose que le mot if et l'espace qui le suit. Cela devrait faire ce que vous voulez:

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

Ce désordre au milieu est de satisfaire votre désir de ne pas utiliser .*?, mais je ne pense pas vraiment que ça vaut la peine. L'approche .*? devrait fonctionner correctement si vous compilez l'expression régulière avec l'ensemble d'indicateurs Re.S ou l'enveloppez dans (?s:...). Par exemple:

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