Мне нужно регулярное выражение, которое может соответствовать условным комментариям на исходной странице 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 не выполняет синтаксический анализ и предоставляет неполный исходный код
РЕДАКТИРОВАТЬ2: [если IE] - не единственное условие. Их гораздо больше, и у меня нет списка всех возможных комбинаций.
РЕДАКТИРОВАТЬ3: Решение Винко Врсаловича работает, но настоящая проблема, почему beautifulsoup не удалось, была связана с ложным комментарием в условном комментарии. Нравиться
<!--[if lt IE 7.]>
<script defer type = "text/javascript" src = "pngfix_253168.js"></script><!--png fix for IE-->
<![endif]-->
Заметили комментарий <!--png fix for IE-->?
Хотя моя проблема была решена, я хотел бы получить для этого решение с регулярным выражением.
@Vinko Vrsalovic: Вы можете выполнить предварительное сопоставление, чтобы предотвратить. *? использование: regular-expressions.info/lookaround.html
Почему вы хотите избегать не жадных. *? построить?






Не используйте для этого регулярные выражения. Вы запутаетесь по поводу комментариев, содержащих открывающие теги, а что нет, и сделаете неправильно. HTML не является регулярным, и попытка изменить его с помощью одного регулярного выражения потерпит неудачу.
Используйте для этого парсер HTML. BeautifulSoup - хороший, простой, гибкий и надежный, способный обрабатывать реальный (то есть безнадежно сломанный) HTML. С его помощью вы можете просто просмотреть все узлы комментариев, изучить их содержимое (вы можете использовать регулярное выражение для который, если хотите) и удалить их, если их нужно удалить.
Строго говоря, условные комментарии - это не HTML, а встроенный макроязык, который AFAIK не может быть вложенным. Так что регулярное выражение может работать.
@Benoit
Малая коррекция (при включенной многострочности):
"<!--\[if IE\]>.*?<!\[endif\]-->"
Вы читали часть «Я бы также хотел по возможности избегать использования нотации. *?»?
Это работает в Visual Studio 2005, где нет параметра диапазона строк:
\<!--\[if 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>
>>>
python 3 с 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, вы можете исправить перед этим или настроить парсер, среди других решений.
Обновлено: в соответствии с вашим комментарием вы просто изменяете лямбду, переданную на findAll, как вам нужно (я изменил ее)
Это было полезно, но я не хочу терять все теги комментариев. Только условные комментарии css.
Вот что вам понадобится:
<!(|--)\[[^\]]+\]>.+?<!\[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) в качестве замены. Я знаю, что есть. *? и. +? в нем смотрите мой комментарий к этому посту.
Вы можете избежать. +? синтаксис, выполнив прямую ссылку, но у меня нет с собой книги регулярных выражений для точного синтаксиса: P
Я бы просто пошел с:
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--->'
Примечание: [^ ¤] будет соответствовать любому символу, кроме '¤'. Это действительно полезно, так как работает молниеносно, и этот символ можно найти на любой клавиатуре. Но хитрость в том, что набирать его действительно сложно (никто не наберет его по ошибке) и никто не использует его: это обычный символ денежного изобретения.
Однако, если вы не хотите использовать ¤, вы можете использовать chr (7) для генерации символа «системный звонок», который не печатается и не может быть найден на веб-странице ;-)
Спасибо, что заметили опечатку. Очевидно, я имел в виду ¤, общий знак валюты, а не ø, которая является обычной буквой.
"е-сатис", это здорово. Лучший ответ и для меня единственное решение! Более того, он сохранился 12 лет! :)
На мой взгляд, вам нужно беспокоиться только о комментариях скрытый на нижнем уровне (тех, которые начинаются с <!--), и вам не нужно ничего сопоставлять, кроме слова if и пробела после него. Это должно делать то, что вы хотите:
"<!--\[if\s(?:[^<]+|<(?!!\[endif\]-->))*<!\[endif\]-->"
Этот беспорядок посередине призван удовлетворить ваше желание не использовать .*?, но я не думаю, что это того стоит. Подход .*? должен работать нормально, если вы скомпилируете регулярное выражение с установленным флагом Re.S или оберните его в (?s:...). Например:
"(?s:<!--\[if\s.*?<!\[endif\]-->)"
Без .*? их нет, особенно если вы не знаете все возможные комбинации, как бы вы их все поймали без. * или подобного? А модификатор non-greedy нужен, если условных комментариев больше одного ...