我有一个带有西班牙文字的UTF-8文件,并且某些带有重音符号的字词在某些软件中显示不正确。
我相信我的档案是正确的。例如,名称“JESÚS”编码为4A 45 53 C3 9A 53
。
>>> b'\x4A\x45\x53\xC3\x9A\x53'.decode('utf-8')
'JESÚS'
根据{{3}}, c39a
是\u00da
的正确UTF-8编码。
那么,为什么某些软件会错误地呈现它呢?
答案 0 :(得分:3)
这是使用Latin-1编码而不是UTF-8的结果。双字节UTF-8序列被错误地解码为两个字符。
>>> 'Ú'.encode('utf-8').decode('latin-1')
'Ã\x9a'
>>> 'É'.encode('utf-8').decode('latin-1')
'Ã\x89'
http://www.fileformat.info/info/unicode/char/00da/index.htm http://www.fileformat.info/info/unicode/char/9a/index.htm
这两个字符都是控制字符,因此它们可能会也可能不会显示在不同的软件中。
此外,重复不正确的编码 - 解码会进一步破坏文本:
>> 'Ú'.encode('utf-8').decode('latin-1').encode('utf-8').decode('latin-1')
'Ã\x83Â\x9a'
更新:如果您看到实际的š和‰(而不是不可见的控制字符),则错误的编码是Windows-1252。
http://www.fileformat.info/info/unicode/char/89/index.htm是Windows-1252的超集,可打印字符为0x80-0x9f。
在Windows-1252中,代码点0x9a和0x89对应于字符š
和‰
:
ISO 8859-1
http://www.fileformat.info/info/unicode/char/0161/index.htm
>>> 'Ú'.encode('utf-8').decode('Windows-1252')
'Ú'
>>> 'É'.encode('utf-8').decode('Windows-1252')
'É'
答案 1 :(得分:2)
您正在使用不同编解码器解码数据的软件中打开文件。我猜他们正在Windows 1252 codepage打开它。这导致Mojibake乱码文字。
UTF-8 codec将Unicode代码点编码为变量字节数,具体取决于编码的字符。 Unicode标准的前127个字符(对应于ASCII标准)只需要一个字节,然后按照1920个Latin-1字符编码为两个字节等,一直到4个字节(UCS允许最多6个字节)每个代码点的字节数。)
您的文字包含2个Latin-1字符,因此每个字符需要2个字节:
>>> u'Ú and É'.encode('utf8')
'\xc3\x9a and \xc3\x89'
请注意空格和单词and
如何编码为单个字节(Python将它们显示为我们的ASCII代码点,因为它比\x..
转义序列更具可读性。
您的某些软件使用不同的编解码器解码该数据。 CP1252编解码器将每个字节解码为单个字符,因此C3
被解码为Ã
,而9A
映射到š
和{{ 1}}到89
:
‰
请注意,该示例中的ASCII字符(空格和单词>>> u'Ú and É'.encode('utf8').decode('cp1252')
u'\xc3\u0161 and \xc3\u2030'
>>> print u'Ú and É'.encode('utf8').decode('cp1252')
Ú and É
)不受影响,因为UTF-8和CP1252都使用这些字符的确切字节;两者都使用ASCII作为前127个字节。
答案 2 :(得分:0)
自动检测文本编码是不可靠的。虽然对于我们人类而言,在许多情况下,在一些练习之后它显而易见,无论你想出什么样的程序,都可能因某些文本输入而失败。例如,讨论字符破碎编码的文本,如此页面(!)
因此,许多使用文本的程序根本不进行自动检测,而是依赖于指定编码的用户。
使用Unicode,有 BOM (Byte Order Mark)可以为您提供帮助。在UTF-8中,如果您使用8位字符0xEF 0xBB 0xBF
开始文本,它可以帮助某些程序确认整个文本的编码。
解释HTML文本的另一大类程序 - 然后您可以使用讨论选项的问题中显示的元标记:
<meta charset="utf-8"> vs <meta http-equiv="Content-Type">
对于所有其他程序,它们都是它们 - 您是否有任何想要工作的示例?