在Python中将utf-8转换为latin-1

3

我想要做这件事情:

获取这个utf-8字符串的字节:

访视频

将这些字节用latin-1编码并打印结果:

访视频

如何在Python中实现这个功能?

# -*- coding: utf-8
s = u'访视频'.encode('latin-1')

引发此异常的原因:

s = u'访视频'.encode('latin-1')
UnicodeEncodeError: 'latin-1' codec can't encode characters in position 0-2: ordinal not in range(256)
2个回答

7
您所要求的事情实际上是不可能的。您不能将那些字符编码为Latin-1,因为那些字符在Latin-1中不存在。
要获得您想要的输出,您需要将UTF-8字节“解码”,就像它们是Latin-1一样。就像这样:
s = u'访视频'.encode('utf-8').decode('latin-1')

然而,你想要的输出并不像实际的Latin-1编码,因为在Latin-1中,字符\x86\x91是无法打印的,所以你会得到这样的结果:
è®¿è§ é¢

(注意中间的空格代替†,以及末尾缺少的‘;这些实际上是不可见的控制字符,而不是空格。)
看起来你想要一个Latin-1超集,可能是Windows代码页1252。如果是这样,你真正需要的是:
s = u'访视频'.encode('utf-8').decode('cp1252')

嗯,我在使用Mac,并使用ISO-8559-1编码检索了该字符串,但你的第二个示例恰好是我想要的。谢谢! - OregonTrail
@OregonTrail:很多网站、文本文件等声称它们采用的是ISO-8859-1编码(不是8559,但我确定那只是一个无意义的打字错误),实际上它们采用的是某个扩展版本,因为作者不知道其中的区别。尤其是Windows用户,他们认为自己的OEM代码页(通常是cp1252)就是Latin-1编码。(以前偶尔也会看到Windows使用的代码页将MacRoman重新映射成类似于Latin-1的编码,我忘记了它的编号,但那是很久以前的事情了。) - abarnert
有没有办法做相反的操作?将"访视频"转换回"访视频"。我似乎无法使它正常工作。 - OregonTrail
好的,所以s.encode('latin-1').decode('utf-8')在这个例子中显然是有效的,但是在我的实际代码库中,我遇到了一个更大的问题,我无法确定原因。 - OregonTrail
@OregonTrail:正如我在答案中解释的那样,\x86\x91是不可打印的控制字符,而不是,在Latin-1中没有任何东西是。因此,当然"访视频".encode('latin-1')会给你一个异常。但是,如果你使用答案中解释的encode('cp1252'),它就可以正常工作。 - abarnert

2

您需要先将内容编码为UTF-8UTF-8可以编码任何Unicode字符串),并且完全兼容7位ASCII集合(任何ASCII字节串都是正确的UTF-8编码字符串)。

>>> u'访视频'.encode('UTF-8').decode('latin-1')
u'\xe8\xae\xbf\xe8\xa7\x86\xe9\xa2\x91'

注意UTF-8 编码可以处理任何 Unicode 字符。它还向后兼容 ASCII,因此纯 ASCII 文件也可以被视为 UTF-8 文件,并且仅使用 ASCII 字符的 UTF-8 文件与具有相同字符的 ASCII 文件相同。


3
是的,但并非每个 latin-1 字符串都不是有效的 utf-8 字符串。 - OregonTrail

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