正则表达式删除条件注释
我想要一个正则表达式,可以匹配HTML源页面中的条件注释,因此我只能删除那些正则表达式。我想保留常规评论。
我也想避免使用。*?表示法(如果可能)。
文字是
foo <!--[if IE]> <style type="text/css"> ul.menu ul li{ font-size: 10px; font-weight:normal; padding-top:0px; } </style> <![endif]--> bar
并且我想删除<!-[如果IE]>
和<![endif]->
中的所有内容
编辑:这是因为BeautifulSoup我想删除这些标签。 BeautifulSoup无法解析,并提供了不完整的来源
EDIT2:[如果IE]不是唯一条件。还有很多,我没有所有可能组合的任何列表。
编辑3:Vinko Vrsalovic的解决方案有效,但是beautifulsoup失败的实际问题是由于条件注释中的流氓注释。喜欢
<!--[if lt IE 7.]> <script defer type="text/javascript" src="pngfix_253168.js"></script><!--png fix for IE--> <![endif]-->
注意IE的<!-png修复->`注释吗?
尽管我的问题是解决,但我很乐意为此获得一个正则表达式解决方案。
解决方案
请勿为此使用正则表达式。我们会对包含开头标签的注释和不包含注释的注释感到困惑,并且做错了事。 HTML不是常规的,尝试使用单个常规表达式对其进行修改将失败。
为此使用HTML解析器。 BeautifulSoup是一种好,易用,灵活且坚固的工具,能够处理真实世界(意味着绝望的坏掉)的HTML。使用它,我们可以查找所有注释节点,检查其内容(如果需要,可以使用正则表达式),如果需要将其删除,则将其删除。
@Benoit
小校正(启用多行功能):
"<!--\[if IE\]>.*?<!\[endif\]-->"
这在没有行跨度选项的Visual Studio 2005中有效:
\ <!-\ [如果是IE \] \> {。| \ n} * \ <!\ [endif \]-\>
>>> 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> >>>
带有bf4的python 3:
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感到困惑,则可以在其他解决方案中事先修复它或者自定义解析器。
编辑:根据评论,我们只需根据需要修改传递给findAll的lambda(我对其进行了修改)
这是我们需要的:
<!(|--)\[[^\]]+\]>.+?<!\[endif\](|--)>
它将过滤掉各种条件注释,包括:
<!--[if anything]> ... <[endif]-->
和
<![if ! IE 6]> ... <![endif]>
EDIT3: Vinko Vrsalovic's solution works, but the actual problem why beautifulsoup failed was because of a rogue comment within the conditional comment. Like Notice the comment? Though my problem was solve, I would love to get a regex solution for this.
这个怎么样:
(<!(|--)\[[^\]]+\]>.*?)(<!--.+?-->)(.*?<!\[endif\](|--)>)
在该正则表达式上执行替换,剩下\ 1 \ 4(或者$ 1 $ 4)作为替换。
我知道它有*。和。+?在其中,请参阅我对此信息的评论。
我只是选择:
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:[^]将匹配不是''的任何字符。这非常有用,因为它闪电般快,并且可以在任何键盘上找到此字符。但是诀窍在于,它真的很难键入(没有人会错误地键入它)并且没有人使用它:这是一种通用的货币设计char。
但是,如果我们不想使用,可以使用chr(7)生成" system bell"字符,该字符不可打印并且无法在网页中找到;
正如我所看到的,我们只需要担心下层隐藏的注释(以<!-开头的注释),并且不需要匹配单词if和后面的空格。这应该做我们想要的:
"<!--\[if\s(?:[^<]+|<(?!!\[endif\]-->))*<!\[endif\]-->"
中间那堆烂摊子是为了满足我们不使用。*?
的愿望,但我并不认为值得付出努力。如果我们使用设置了Re.S标志的正则表达式或者将其包装在(?s:...)
中,则。*?
方法应该可以正常工作。例如:
"(?s:<!--\[if\s.*?<!\[endif\]-->)"