UTF-8 到 ISO-8859-1 编码:用最接近的等效字符替换特殊字符

UTF-8 to ISO-8859-1 encoding: replace special characters with closest equivalent

有谁知道 Python 库允许您以智能方式将 UTF-8 字符串转换为 ISO-8859-1 编码?

所谓聪明,是指将“–”等字符替换为“-”左右。对于许多实在想不出对应物的字符,用“?”代替(就像 encode('iso-8859-1', errors='replace') 那样)。

嗯,我不知道有任何现有的库,但是 Unidecode 有 GPL 2 许可证,这意味着它可以用作另一个程序的基础。它的主要功能是对所有 ASCII 代码点(128 以下)进行特殊处理,使它们保持不变。如果您只是将该处理扩展到 Latin1 字母(代码点低于 256),您将获得一个保留 Latin1 字符并对所有其他字符使用 unidecode 的特殊版本。

据我所知,没有超过 255 的字符应该映射到 latin1 非 ascii 字符,这应该可以解决问题。

libiconv 有一个 "TRANSLIT" 功能可以满足您的需求

由于 Unicode 的前 256 个代码点与 ISO-8859-1 匹配,因此可以尝试编码为 ISO-8859-1,这将无误地处理所有字符 0 到 255。对于导致编码错误的字符,可以使用unidecode。

以下作品适用于 Python 2 和 3:

from builtins import str
import unidecode

def unidecode_fallback(e):
    part = e.object[e.start:e.end]
    replacement = str(unidecode.unidecode(part) or '?')
    return (replacement, e.start + len(part))

codecs.register_error('unidecode_fallback', unidecode_fallback)

s = u'abcdé–fghijkl'.encode('iso-8859-1', errors='unidecode_fallback')
print(s.decode('iso-8859-1'))

结果:

abcdé-fgh?ijkl

然而,这会将非 ISO-8859-1 字符转换为 ASCII 等效字符,而有时使用非 ASCII、ISO-8859-1 等效字符可能更好。