正则表达式删除条件注释

时间:2008-09-25 10:23:33

标签: python regex

我想要一个可以在HTML源页面中匹配条件注释的正则表达式,所以我只能删除那些。我想保留常规评论。

我还想避免使用。*?符号如果可能的话。

文字是

foo

<!--[if IE]>

<style type="text/css">

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

</style>

<![endif]-->

bar

我希望删除<!--[if IE]><![endif]-->

中的所有内容

编辑:由于BeautifulSoup,我想删除这些标签。 BeautifulSoup无法解析并提供不完整的来源

EDIT2: [如果IE]不是唯一的条件。还有更多,我没有任何可能的组合列表。

EDIT3: Vinko Vrsalovic的解决方案有效,但是为什么beautifulsoup失败的实际问题是由于条件评论中的流氓评论。像

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

请注意<!--png fix for IE-->评论?

虽然我的问题已解决,但我很乐意为此获得正则表达式解决方案。

7 个答案:

答案 0 :(得分: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 with 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())

如果你的数据让BeautifulSoup感到困惑,你可以事先fix或者customize解析器,以及其他解决方案。

编辑:根据您的评论,您只需根据需要修改传递给findAll的lambda(我对其进行了修改)

答案 1 :(得分:2)

以下是您需要的内容:

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

它将过滤掉各种条件评论,包括:

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

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

  

EDIT3 :Vinko Vrsalovic的解决方案有效,但是beautifulsoup失败的实际问题是由于条件评论中的流氓评论。像

     

           

     

注意评论?

     

虽然我的问题已解决,但我很乐意为此获得正则表达式解决方案。

这个怎么样:

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

替换正则表达式,将\ 1 \ 4(或$ 1 $ 4)作为替换 我知道它有。*?和。+?在其中,请参阅我对此帖的评论。

答案 2 :(得分:2)

在我看来,你只需要担心下层隐藏的评论(以<!--开头的评论),你不需要匹配任何字词以外的内容if及其后的空格。这应该做你想要的:

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

中间的混乱是为了满足你不使用.*?的愿望,但我并不认为这是值得的。如果您使用Re.S标志集编译正则表达式或将其包装在.*?中,(?s:...)方法应该可以正常工作。例如:

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

答案 3 :(得分:1)

@Benoit

小修正(多线打开):

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

答案 4 :(得分:1)

我只是选择:

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:[^¤]将匹配任何不是'¤'的字符。这非常有用,因为它快速闪电,这个字符可以在任何键盘上找到。但诀窍是它很难输入(没有人会错误地输入它)并且没有人使用它:它是一种通用的货币设计。

但是,如果您不想使用¤,则可以使用chr(7)生成“系统铃”字符,这是不可打印的,无法在网页中找到; - )

答案 5 :(得分:0)

不要使用正则表达式。您会对包含开始标记的评论感到困惑,哪些不是,并做错了。 HTML不常规,尝试使用单个正则表达式修改它将失败。

为此使用HTML解析器。 BeautifulSoup是一个优秀,简单,灵活和坚固的,能够处理真实世界(意味着无可救药地破坏)的HTML。有了它,您只需查找所有注释节点,检查其内容(如果您愿意,可以使用 的正则表达式),如果需要删除它们,请将其删除。

答案 6 :(得分:0)

这适用于Visual Studio 2005,其中没有行间距选项:

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