您的问题有两个部分。最简单的部分是解码 HTML 实体。最简单的方法是从HTMLParser 模块中获取这个未记录但长期稳定的方法:
>>> HTMLParser.HTMLParser().unescape('a < é – …')
u'a < é – …'
第二部分,将 Unicode 字符转换为类似 ASCII 的字符,比较棘手,也很值得怀疑。我会尝试保留 Unicode 破折号“-”和类似的印刷细节,而不是将它们转换为普通连字符和直引号之类的字符。除非您的应用程序根本无法处理非 ASCII 字符,否则您应该将它们与所有其他 Unicode 字符一起保持原样。
U+2013 省略号字符的具体情况可能会有所不同,因为它是一个“兼容字符”,包含在 Unicode 中仅用于无损往返到具有它的其他编码。最好只输入三个点,然后让字体的字形组合逻辑准确计算出如何绘制它。
如果您只想替换兼容性字符(例如,显式连字、日文全角数字和一些其他奇怪的字符),您可以尝试将您的字符串规范化为范式 KC:
>>> unicodedata.normalize('NFKC', u'a < – …')
u'a < é – ...'
(但请注意:您可能想要保留的其他一些字符也是兼容字符,包括“²”。)
下一步是将带有变音符号的字母转换为普通字母,您可以通过规范化为 NFKD 来做到这一点,并从字符串中删除所有具有“组合”字符类的字符。这将为您提供以前重音拉丁字母的纯 ASCII,尽管对于许多语言而言,这种方式在语言上并不正确。如果您只关心这些,您可以直接编码为 ASCII:
>>> unicodedata.normalize('NFKD', u'a < – …').encode('us-ascii', 'ignore')
'a < e ...'
您可能做的任何进一步的事情都必须是临时的,因为没有可接受的标准将字符串折叠成 ASCII。 Windows 有一种实现,Lucene (ASCIIFoldingFilter) 也是如此。结果参差不齐。