从字符串中删除 html 图像标签和介于两者之间的所有内容
Posted
技术标签:
【中文标题】从字符串中删除 html 图像标签和介于两者之间的所有内容【英文标题】:Removing html image tags and everything in between from a string 【发布时间】:2012-05-16 04:39:06 【问题描述】:我已经看到了很多关于从字符串中删除 html 标记的问题,但我仍然不太清楚应该如何处理我的具体情况。
我看到许多帖子建议不要使用正则表达式来处理 HTML,但我怀疑我的情况可能需要明智地规避这条规则。
我正在尝试解析 PDF 文件,并且成功地将示例 PDF 文件中的每一页转换为 UTF-32 文本字符串。当图像出现时,会插入一个 HTML 样式的标签,其中包含图像的名称和位置(保存在其他地方)。
在我的应用程序的一个单独部分中,我需要摆脱这些图像标签。因为我们只处理图像标签,我怀疑可能需要使用正则表达式。
我的问题有两个:
-
我应该使用正则表达式来删除这些标签,还是应该使用 HTML 解析模块,例如 BeautifulSoup?
我应该使用哪个正则表达式或 BeautifulSoup 构造?换句话说,我应该如何编码?
为清楚起见,标签的结构为<img src="/path/to/file"/>
谢谢!
【问题讨论】:
此文件中是否还有其他 HTML?还是只是纯文本和<img>
标签?
@senderle 不,除了 标签之外没有 HTML,因此我对使用成熟的 HTML 库犹豫不决。格式是总是我上面描述的那样。
我刚刚发布了一个答案,但我想知道,在每张图片的关闭 > 之后实际上是否有一个撇号,或者这是一个错字?
@joshcartme 好收获!那确实是一个错字!
好吧,我打算更新我在下面发布的答案以处理撇号 =)
【参考方案1】:
我会投票认为在您的情况下使用正则表达式是可以接受的。像这样的东西应该可以工作:
def remove_html_tags(data):
p = re.compile(r'<.*?>')
return p.sub('', data)
我在这里找到了 sn-p (http://love-python.blogspot.com/2008/07/strip-html-tags-using-python.html)
编辑:仅删除 <img .... />
:
def remove_img_tags(data):
p = re.compile(r'<img.*?/>')
return p.sub('', data)
【讨论】:
我之前也看过那个页面,但我对所讨论的正则表达式有点困惑(请注意,我对正则表达式的使用一无所知)。为什么.*?
字符串?它不应该读成<img src*>
之类的东西吗?
我发布的第一个工作方式是删除 之间的任何内容。如果您在纯文本中有其他 实例(而不是 html 标签),它会删除它不应该有的东西。我刚刚发布了另一个更具选择性的版本。
又一个小问题。我应该提到我试图摆脱 标记的字符串是 UTF-32 字节串。为了使它起作用,我需要做些什么特别的事情吗?我似乎没有检测到任何 标签...
添加 '?'在 '*' 之后使它不贪婪。
嗯,我不确定 UTF-32 字节串。所以它根本不起作用?【参考方案2】:
由于此文本包含 only 图像标签,因此使用正则表达式可能没问题。但是对于其他任何事情,您最好使用真正的 HTML 解析器。幸运的是 Python 提供了一个!这是非常简单的——要完全发挥作用,它必须处理更多的极端情况。 (最值得注意的是,XHTML 样式的空标签(以斜线 <... />
结尾)在此处未正确处理。)
>>> from HTMLParser import HTMLParser
>>>
>>> class TagDropper(HTMLParser):
... def __init__(self, tags_to_drop, *args, **kwargs):
... HTMLParser.__init__(self, *args, **kwargs)
... self._text = []
... self._tags_to_drop = set(tags_to_drop)
... def clear_text(self):
... self._text = []
... def get_text(self):
... return ''.join(self._text)
... def handle_starttag(self, tag, attrs):
... if tag not in self._tags_to_drop:
... self._text.append(self.get_starttag_text())
... def handle_endtag(self, tag):
... self._text.append('</0>'.format(tag))
... def handle_data(self, data):
... self._text.append(data)
...
>>> td = TagDropper([])
>>> td.feed('A line of text\nA line of text with an <img url="foo"> tag\nAnother line of text with a <br> tag\n')
>>> print td.get_text()
A line of text
A line of text with an <img url="foo"> tag
Another line of text with a <br> tag
并删除img
标签...
>>> td = TagDropper(['img'])
>>> td.feed('A line of text\nA line of text with an <img url="foo"> tag\nAnother line of text with a <br> tag\n')
>>> print td.get_text()
A line of text
A line of text with an tag
Another line of text with a <br> tag
【讨论】:
太棒了,谢谢!我想我现在会走正则表达式路线,因为它似乎涉及更少的代码(简化,简化!)。【参考方案3】:我的解决办法是:
def remove_HTML_tag(tag, string):
string = re.sub(r"<\b(" + tag + r")\b[^>]*>", r"", string)
return re.sub(r"<\/\b(" + tag + r")\b[^>]*>", r"", string)
【讨论】:
以上是关于从字符串中删除 html 图像标签和介于两者之间的所有内容的主要内容,如果未能解决你的问题,请参考以下文章