我是一个初学者,在Python 2.7中无法解码带有数字+(简体)汉字的几十个CSV文件到UTF-8。我不知道输入文件的编码,因此我尝试了所有我知道的可能的编码-GB18030,UTF-7,UTF-8,UTF-16和UTF-32(LE和BE)。同样,尽管它们应该是GB18030的子集,但最好还是使用GBK和GB3212。当它们到达第一个汉字时,UTF都停止。除GB18030外,其他编码在第一行中停止。我认为这将是解决方案,因为它会读取前几个文件并将其正确解码。我的部分代码(逐行阅读)是:line = line.decode("GB18030")我尝试解码的前两个文件工作正常。在第三个文件中途,Python吐出UnicodeDecodeError: 'gb18030' codec can't decode bytes in position 168-169: illegal multibyte sequence在此文件中,大约一百万行中有大约5个此类错误。我在文本编辑器中打开了输入文件,并检查了哪些字符导致了解码错误,并且前几个字符在CSV文件的特定列中都带有欧元符号。我完全有把握这些是错别字,所以我只想删除欧元字符。我想一一检查一下编码错误的类型;我想摆脱所有的欧元错误,但是直到我先看看其他错误之前,我都不想忽略它们。编辑:我使用了chardet,它给GB2312作为所有文件的.99置信度编码。我尝试使用GB2312进行解码,从而得到:UnicodeDecodeError: 'gb2312' codec can't decode bytes in position 108-109: illegal multibyte sequence 最佳答案 “”“ ... GB18030。我认为这是解决方案,因为它会读取前几个文件并将其正确解码。”“”-请解释您的意思。对我来说,成功解码有两个条件:首先,raw_bytes.decode('some_encoding')不会失败,其次,显示的结果unicode在特定语言下有意义。用latin1或iso_8859_1解码时,Universe中的每个文件都将通过第一个测试。东亚语言中的许多文件都通过gb18030进行了首次测试,因为大多数常用的中文,日文和韩文字符是使用相同的两字节序列块进行编码的。您完成了第二次测试的多少?不要在IDE或文本编辑器中查看数据。在网络浏览器中查看它;他们通常可以更好地检测编码。您怎么知道它是欧元字符?通过查看使用哪种编码对原始字节进行解码的文本编辑器的屏幕? cp1252?您怎么知道它包含汉字?您确定不是日语吗?韩国人吗你从哪里得到的?在香港,台湾(可能是澳门)和大陆以外的其他地方创建的中文文件使用big5或big5_hkscs编码-尝试这样做。无论如何,请听取马克的建议并指向chardet;如果文件足够大且已正确编码中文/日文/韩文,则chardet通常可以很好地检测所使用的编码-但是,如果有人使用文本编辑器使用单字节字符集手动编辑文件,一些非法字符可能会导致其他99.9%的字符使用的编码无法被检测到。您可能想对文件中的5行执行print repr(line)并将输出编辑为您的问题。如果文件不是机密文件,则可能希望将其下载。是在Windows上创建的文件吗?您如何用Python阅读它? (显示代码)OP评论后更新:记事本等不要试图猜测编码;默认值为“ ANSI”。您必须告诉它该怎么做。您所说的欧元字符是由编辑器使用您环境的默认编码解码的原始字节“ \ x80”,通常怀疑是“ cp1252”。不要使用这样的编辑器来编辑文件。之前您在谈论“前几个错误”。现在,您说总共有5个错误。请解释。如果该文件的确几乎是正确的gb18030,则应该能够逐行解码该文件,并且当出现此类错误时,将其捕获,打印错误消息,从消息中提取字节偏移,然后打印repr(two_bad_bytes) ,并继续前进。我对\x80出现在两个字节中的哪个非常感兴趣。如果根本没有出现,则“欧洲字符”不是您的问题的一部分。请注意,\x80可以有效地出现在gb18030文件中,但只能作为2字节序列中从\x81到\xfe的第二个字节出现。在尝试解决问题之前,先了解您的问题是一个好主意。尝试通过在“ ANSI”模式下用记事本等重击来修复它不是一个好主意。您对如何确定gb18030解码的结果有意义感到非常co恼。特别是,我将仔细检查gbk失败但gb18030“有效”的行-那里一定有一些极为罕见的中文字符,或者也许是一些非中文非ASCII字符...这是检查损坏程度的更好方法的建议:使用raw_bytes.decode(encoding, 'replace')解码每个文件并将结果(以utf8编码)写入另一个文件。用result.count(u'\ufffd')计算错误。查看用于确定gb18030解码有意义的内容的输出文件。 U + FFFD字符应显示为黑色菱形内的白色问号。如果您决定可以丢弃不可分解的碎片,最简单的方法是raw_bytes.decode(encoding, 'ignore')进一步的信息更新所有这些\\令人困惑。看来,“获取字节”涉及repr(repr(bytes))而不是repr(bytes) ...,在交互式提示下,执行bytes(您将得到一个隐含的repr())或print repr(bytes)(这将赢得没有得到隐式的repr()空格:我假设您的意思是'\xf8\xf8'.decode('gb18030')是您要解释的某种全角空格,并且解释是通过使用某些无命名查看器软件的视觉检查完成的。那是对的吗?实际上是'\xf8\xf8'.decode('gb18030')-> u'\e28b'。 U + E28B在Unicode PUA(专用区域)中。 “空白”可能意味着查看器软件毫无疑问没有使用的字体中的U + E28B字形。也许文件的来源是故意使用PUA来处理不在标准gb18030中的字符,用于注释或用于传输伪秘密信息的。如果是这样,您将需要使用解码手鼓,这是俄罗斯最近的研究reported here的分支。备选方案:cp939-HKSCS理论。根据香港政府的说法,HKSCS big5代码FE57曾经映射到U + E28B,但现在映射到U + 28804。“ euro”:您说“”“由于数据我无法共享整行,但是我所说的欧元字符位于:\ xcb \ xbe \ x80 \ x80” [我假设从一开始就被省略了,而\是文字]。 “欧洲字符”(出现时)始终位于我不需要的同一列中,因此我希望只使用“忽略”。不幸的是,由于“ euro char”正好在文件中的引号旁边,因此有时“忽略”会同时删除欧元字符和引号,这给csv模块确定列“”带来了麻烦”如果您可以显示这些"字节相对于引号和汉字的显示方式,将大有帮助-仅显示十六进制即可保持可读性,并隐藏您的机密数据,例如通过使用C1 C2来表示“我确定可以表示一个汉字的两个字节”。例如:C1 C2 C1 C2 cb be 80 80 22 # `\x22` is the quote character请提供以下示例:(1)不会丢失“替换”或“忽略”(2)导致引用丢失。在迄今为止唯一的示例中,“不会丢失:>>> '\xcb\xbe\x80\x80\x22'.decode('gb18030', 'ignore')u'\u53f8"'并且向您发送一些调试代码的提议(请参见下面的示例输出)仍处于打开状态。>>> import decode_debug as de>>> def logger(s):... sys.stderr.write('*** ' + s + '\n')...>>> import sys>>> de.decode_debug('\xcb\xbe\x80\x80\x22', 'gb18030', 'replace', logger)*** input[2:5] ('\x80\x80"') doesn't start with a plausible code sequence*** input[3:5] ('\x80"') doesn't start with a plausible code sequenceu'\u53f8\ufffd\ufffd"'>>> de.decode_debug('\xcb\xbe\x80\x80\x22', 'gb18030', 'ignore', logger)*** input[2:5] ('\x80\x80"') doesn't start with a plausible code sequence*** input[3:5] ('\x80"') doesn't start with a plausible code sequenceu'\u53f8"'>>>尤里卡:-有时丢失引号字符的可能原因-\x80解码器替换/忽略机制中似乎存在错误:gb18030不是有效的gb18030前导字节;当检测到解码器时,解码器应尝试与NEXT字节重新同步。但是,它似乎忽略了\x80和以下字节:>>> '\x80abcd'.decode('gb18030', 'replace')u'\ufffdbcd' # the 'a' is lost>>> de.decode_debug('\x80abcd', 'gb18030', 'replace', logger)*** input[0:4] ('\x80abc') doesn't start with a plausible code sequenceu'\ufffdabcd'>>> '\x80\x80abcd'.decode('gb18030', 'replace')u'\ufffdabcd' # the second '\x80' is lost>>> de.decode_debug('\x80\x80abcd', 'gb18030', 'replace', logger)*** input[0:4] ('\x80\x80ab') doesn't start with a plausible code sequence*** input[1:5] ('\x80abc') doesn't start with a plausible code sequenceu'\ufffd\ufffdabcd'>>>
08-05 11:03