从字符串中删除 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)

编辑:仅删除 &lt;img .... /&gt;:

形式的内容的版本
def remove_img_tags(data):
    p = re.compile(r'<img.*?/>')
    return p.sub('', data)

【讨论】:

我之前也看过那个页面,但我对所讨论的正则表达式有点困惑(请注意,我对正则表达式的使用一无所知)。为什么.*? 字符串?它不应该读成&lt;img src*&gt; 之类的东西吗? 我发布的第一个工作方式是删除 之间的任何内容。如果您在纯文本中有其他 实例(而不是 html 标签),它会删除它不应该有的东西。我刚刚发布了另一个更具选择性的版本。 又一个小问题。我应该提到我试图摆脱 标记的字符串是 UTF-32 字节串。为了使它起作用,我需要做些什么特别的事情吗?我似乎没有检测到任何 标签... 添加 '?'在 '*' 之后使它不贪婪。 嗯,我不确定 UTF-32 字节串。所以它根本不起作用?【参考方案2】:

由于此文本包含 only 图像标签,因此使用正则表达式可能没问题。但是对于其他任何事情,您最好使用真正的 HTML 解析器。幸运的是 Python 提供了一个!这是非常简单的——要完全发挥作用,它必须处理更多的极端情况。 (最值得注意的是,XHTML 样式的空标签(以斜线 &lt;... /&gt; 结尾)在此处未正确处理。)

>>> 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 图像标签和介于两者之间的所有内容的主要内容,如果未能解决你的问题,请参考以下文章

比较 NSDates 以检查今天是不是介于两者之间

Laravel 查询生成器介于两者之间

删除图像标签 HTML/CSS 之间的水平间隙 [重复]

python迭代器、生成器和介于两者之间

如何从字符串中删除 \n 和 \r

<option> 标签中有多个值?