Python - Unicode转ASCII转换

15

我无法将以下Unicode转换为ASCII而不丢失数据:

u'ABRA\xc3O JOS\xc9'

我尝试了 encodedecode,但它们没有完成。

有人有建议吗?


你实际上需要编码为 ASCII 吗,还是只需要“某些 8 位字符集”或“我的平台默认的 8 位字符集”或类似的内容? - abarnert
它是ASCII编码。数据库连接被设置为ASCII编码。 - Adriano Almeida
1
作为参考,Unicode 中的字符串看起来像 _ABRAÃO JOSÉ_。 - nealmcb
3个回答

40

Unicode字符u'\xce0'u'\xc9'没有对应的ASCII值。因此,如果您不想丢失数据,就必须以某种作为ASCII有效的方式对该数据进行编码。选项包括:

>>> print s.encode('ascii', errors='backslashreplace')
ABRA\xc3O JOS\xc9
>>> print s.encode('ascii', errors='xmlcharrefreplace')
ABRAÃO JOSÉ
>>> print s.encode('unicode-escape')
ABRA\xc3O JOS\xc9
>>> print s.encode('punycode')
ABRAO JOS-jta5e

所有这些都是ASCII字符串,它们包含了原始Unicode字符串的所有信息(因此它们都可以被反转而不丢失数据),但对于最终用户来说它们并不够美观(而且没有哪个字符串能仅通过decode('ascii')进行反转)。

有关更多信息,请参见str.encodePython特定编码Unicode HOWTO


顺便提一下,当有些人说“ASCII”时,他们真正指的并不是“ASCII”,而是“任何ASCII超集的8位字符集”或“某个我想到的特定8位字符集”。如果你是这个意思,解决方案就是编码为正确的8位字符集:

>>> s.encode('utf-8')
'ABRA\xc3\x83O JOS\xc3\x89'
>>> s.encode('cp1252')
'ABRA\xc3O JOS\xc9'
>>> s.encode('iso-8859-15')
'ABRA\xc3O JOS\xc9'

困难的部分在于搞清楚您想要使用哪个字符集。如果您正在编写生成8位字符串和消耗它的代码,并且您不知道更好的选择,那么您应该使用UTF-8。但是如果消耗8位字符串的代码是 open 函数、您提供页面服务的Web浏览器或其他任何东西,情况会更加复杂,没有足够的信息就很难给出简单答案。


谢谢。那很有帮助。我已经使用了xmlcharrefreplace,但是当我写入Oracle DB时,它会在我的字符串中放入垃圾字符。我通过更改NLS_LANG参数来解决了这个问题。os.environ["NLS_LANG"] = "AMERICAN_AMERICA.WE8ISO8859P1",然后转换为"latin-1"。 - Adriano Almeida
请注意,尽管Latin-1/ISO-8859-1可以处理您现有的两个字符,但它无法处理大多数Unicode。因此,一旦有人试图给您提供俄语或中文名称,您将收到“UnicodeError”。如果您可以设置Oracle使用UTF-8,那么您将避免任何这样的未来问题。如果您不能...只需记住这一点,并相应地设计您的测试。 - abarnert

1
我发现这个库https://pypi.org/project/Unidecode/非常有用。
>>> from unidecode import unidecode
>>> unidecode('ko\u017eu\u0161\u010dek')
'kozuscek'
>>> unidecode('30 \U0001d5c4\U0001d5c6/\U0001d5c1')
'30 km/h'
>>> unidecode('\u5317\u4EB0')
'Bei Jing '

0

我需要计算从HTTP请求中接收到的unicode字符串MD5哈希值。但是,使用MD5时会出现UnicodeEncodeError错误,并且Python内置的编码方法无法解决此问题,因为它将字符串中的字符替换为相应的十六进制值,从而改变了MD5哈希值

因此,我想出了以下代码,它在从unicode转换时保持字符串不变。

unicode_string = ''.join([chr(ord(x)) for x in unicode_string]).strip()

这将从字符串中删除unicode部分,并保留所有数据不变。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接