我仍然不知道是否有一种方法可以将’ó’从latin-1正确转换为utf-8而不进行任何处理
在调试此类问题时,repr()和unipredata.name()是您的朋友:
>>> oacute_latin1 = "xF3">>> oacute_unipre = oacute_latin1.depre('latin1')>>> oacute_utf8 = oacute_unipre.enpre('utf8')>>> print repr(oacute_latin1)'xf3'>>> print repr(oacute_unipre)u'xf3'>>> import unipredata>>> unipredata.name(oacute_unipre)'LATIN SMALL LETTER O WITH ACUTE'>>> print repr(oacute_utf8)'xc3xb3'>>>如果将oacute_utf8发送到为latin1设置的终端,则将得到A-tilde,后跟上标3。
我切换到Unipre字符串。
您在说什么Unipre字符串?UTF-16?
是什么赋予了?看完这篇文章,描述了我所处的完全相同的情况之后,似乎该建议是忽略其他建议,而毕竟使用8位字节串。
我无法想象您的感觉如何。所传达的故事是,要使用Python中的unipre对象和数据库中的UTF-8编码。但是Martin回答了最初的问题,并为OP提供了一种使用latin1的方法(“文本工厂”),但这并不构成建议!
*针对在评论中提出的其他问题进行 *更新 :
我不明白unipre字符仍然包含隐式编码。我说的对吗?
不能。编码是Unipre与其他内容之间的映射,反之亦然。Unipre字符没有隐式或其他方式的编码。
在我看来,用repr()求值时,unipre(“ xF3”)和“ xF3” .depre(’latin1’)相同。
说什么?在我看来,它看起来并不像:
>>> unipre("xF3")Traceback (most recent call last): File "<stdin>", line 1, in <module>UnipreDepreError: 'ascii' prec can't depre byte 0xf3 in position 0: ordinalnot in range(128)>>> "xF3".depre('latin1')u'xf3'>>>也许您的意思是:
u'xf3' == 'xF3'.depre('latin1')……这确实是事实。也确实
unipre(str_object,encoding)与
str_object.depre(encoding)…相同,包括在提供了不适当的编码时炸毁。
那是一个快乐的情况吗
最好将Unipre中的前256个字符用于代码,因为latin1中的256个字符是一个好主意。因为所有256个可能的latin1字符都映射到Unipre,这意味着可以将任何8位字节,任何Python
str对象解码为unipre,而不会引发异常。这是应该的。
但是,有些人会混淆两个截然不同的概念:“我的脚本运行到完成而没有引发任何异常”和“我的脚本没有错误”。对他们而言,latin1是“一个陷阱和一个妄想”。
换句话说,如果您的文件实际上是用cp1252或gbk或koi8-u或其他格式编码的,并且使用latin1对其进行解码,那么生成的Unipre将完全是垃圾,而Python(或任何其他语言)将不会标记错误-
-它无法知道您犯了傻。
还是unipre(“ str”)总是返回正确的解码?
这样,默认编码为ascii,如果文件实际上是用ASCII编码的,它将返回正确的unipre。否则,它会炸毁。
同样,如果您指定正确的编码,或者是正确编码的超集,则将获得正确的结果。否则会出现乱码或异常情况。
简而言之:答案是否定的。
如果没有,当我收到其中包含任何可能的字符集的python str时,如何知道如何对其进行解码?
如果str对象是有效的XML文档,它将在前面指定。默认值为UTF-8。如果它是正确构建的网页,则应预先指定(查找“字符集”)。不幸的是,许多网页编写者都through之以鼻(ISO-8859-1
aka latin1,应该是Windows-1252 aka
cp1252;不要浪费资源尝试解码gb2312,请改用gbk)。您可以从网站的国籍/语言获得线索。
UTF-8总是值得尝试的。如果数据是ascii,则可以正常工作,因为ascii是utf8的子集。如果您尝试将其解码为utf8,则使用非ASCII字符编写且已使用utf8以外的编码方式编码的文本字符串几乎肯定会失败,但会出现异常。
以上所有启发式方法以及更多以及许多统计信息都封装在chardet中,chardet是一个用于猜测任意文件编码的模块。通常效果很好。但是,您不能使软件不受白痴的影响。例如,如果您将一些编码为A的数据文件与编码B的数据文件串联起来,并将结果输入chardet,答案可能是
置信度降低的 编码C ,例如0.8。 始终检查答案的置信度部分 。
如果其他所有方法均失败:
(1)尝试在此处进行询问,并从数据的
print repr(your_data[:400])开头获取一个小样本… …以及有关其来源的所有附带信息。
(2)俄罗斯最近对恢复忘记密码的技术的研究似乎非常适用于推导未知的编码。
更新2 BTW,是不是您提出另一个问题的时间?-)
还有一件事:Windows显然将某些字符用作某些字符的Unipre,而不是该字符的正确Unipre,因此,如果要在其他程序中使用它们,则可能必须将这些字符映射到正确的字符。期待那些角色在正确的位置。
不是Windows这样做的。这是一群疯狂的应用程序开发人员。可以理解的是,您可能没有措辞,而是引用了effbot文章的开头部分:
某些应用程序将CP1252(Windows,西欧)字符添加到标记为ISO
8859-1(拉丁语1)或其他编码的文档中。这些字符不是有效的ISO-8859-1字符,并且可能在处理和显示应用程序中引起各种问题。
背景:
U + 0000到U + 001F(含)范围在Unipre中指定为“
C0控制字符”。它们也以相同的含义存在于ASCII和latin1中。它们包括诸如回车,换行,铃声,退格键,制表符之类的熟悉的东西,以及其他很少使用的东西。
U + 0080到U + 009F(含)范围在Unipre中指定为“
C1控制字符”。这些也存在于latin1中,包括32个字符,unipre.org之外的任何人都无法想象有任何可能的用途。
因此,如果对unipre或latin1数据进行字符频率计数,并且发现该范围内的任何字符,则数据已损坏。没有通用的解决方案。这取决于它如何损坏。这些字符
可能
与cp1252字符在相同位置具有相同的含义,因此effbot的解决方案将起作用。在我最近查看的另一种情况下,狡猾的字符似乎是由串联以UTF-8编码的文本文件和另一种编码所导致的,这些编码需要根据文件(人类)语言中的字母频率来推断写。



