在Python中将HTML实体转换为其值

2 投票
3 回答
2435 浏览
提问于 2025-04-15 22:16

我在一些输入上使用了这个正则表达式,

[^a-zA-Z0-9@#]

但是这导致很多HTML特殊字符被去掉了,比如说

#227;, #1606;, #1588; (i had to remove the & prefix so that it wouldn't 
show up as the actual value..)

有没有办法可以把这些特殊字符转换成它们的值,这样就能满足这个正则表达式的要求?我也不知道为什么文本会变得这么大。

3 个回答

0

我不知道这个表达式是用来干嘛的,所以我不能确切告诉你你需要什么。

这个表达式会匹配一些特殊字符或者字符组合,但不包括字母、数字、@和#:

[^a-zA-Z0-9@#]*|#[0-9A-Za-z]+;
1

你可以根据下面的脚本进行调整:

import htmlentitydefs
import re

def substitute_entity (match):
    name = match.group (1)
    if name in htmlentitydefs.name2codepoint:
        return unichr (htmlentitydefs.name2codepoint[name])
    elif name.startswith ('#'):
        try:
            return unichr (int (name[1:]))
        except:
            pass

    return '?'

print re.sub ('&(#?\\w+);', substitute_entity, 'x « y &wat; z {')

这样会得到以下的结果:

x « y ? z {

补充:我理解这个问题是“如何在进一步处理之前去掉HTML实体”,希望我没有浪费时间在回答一个错误的问题上;)

4

如果你的文本中包含的是数字编码的实体,而不是命名的实体,你可以先把包含 XML 实体定义的字节字符串(像是&、#、数字和分号)转换成 Unicode 格式:

import re
xed_re = re.compile(r'&#(\d+);')
def usub(m): return unichr(int(m.group(1)))

s = 'ã, ن, ش'
u = xed_re.sub(usub, s)

如果你的终端模拟器可以显示任意的 Unicode 字符,那么使用 print u 就能显示出来

ã, ن, ش

无论如何,如果你愿意,现在可以继续使用你原来的正则表达式,这样就不会意外地“捕获”那些实体,只会匹配 ASCII 字母、数字和你列出的几个标点符号。(我不太确定这是否是你真正想要的——比如,为什么只要 ASCII 字母而不包括带重音的字母呢?——但如果这确实是你想要的,那就可以实现)。

如果你除了数字编码的实体还有命名的实体,你也可以使用 htmlentitydefs 这个标准库模块,它在另一个回答中被推荐过(不过它只处理那些映射到 Latin-1 编码点的命名实体)。

撰写回答