Python中的汉字编码错误
我是一个初学者,在Python2.7中将几十个带有数字+(简体)汉字的CSV文件解码为UTF-8时遇到困难 我不知道输入文件的编码,所以我尝试了我知道的所有可能的编码——GB18030、UTF-7、UTF-8、UTF-16和UTF-32(LE&BE)。此外,为了更好地衡量,GBK和GB3212,尽管它们应该是GB18030的子集。UTF字符在到达第一个汉字时都会停止。除GB18030外,其他编码都停在第一行的某个地方。我认为这将是一个解决方案,因为它读取了前几个文件,并对它们进行了良好的解码。我的部分代码,逐行阅读,是:Python中的汉字编码错误,python,encoding,cjk,Python,Encoding,Cjk,我是一个初学者,在Python2.7中将几十个带有数字+(简体)汉字的CSV文件解码为UTF-8时遇到困难 我不知道输入文件的编码,所以我尝试了我知道的所有可能的编码——GB18030、UTF-7、UTF-8、UTF-16和UTF-32(LE&BE)。此外,为了更好地衡量,GBK和GB3212,尽管它们应该是GB18030的子集。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作为所有文件的0.99置信度编码。我尝试使用GB2312进行解码,得到:
UnicodeDecodeError: 'gb2312' codec can't decode bytes in position 108-109: illegal multibyte sequence
您可以试试。“…GB18030。我认为这将是解决方案,因为它通读了前几个文件并对它们进行了良好的解码。”“--请解释一下您的意思。对我来说,成功解码有两个标准:第一,原始字节.decode(“某些编码”)没有失败,第二,结果显示的unicode在特定语言中有意义。当使用latin1
akaiso_8859_1
解码时,宇宙中的每个文件都将通过第一次测试。东亚语言中的许多文件都通过了gb18030的第一次测试,因为汉语、日语和韩语中的常用字符大多使用相同的两字节序列块进行编码。第二次测试你做了多少
不要在IDE或文本编辑器中查看数据。在网络浏览器中查看它;它们通常能更好地检测编码
你怎么知道这是一个欧洲角色?通过查看正在使用什么编码对原始字节进行解码的文本编辑器的屏幕?cp1252
你怎么知道它包含汉字?你确定不是日本人吗?韩国人你从哪里弄来的
香港、台湾、澳门、内地等地方的文件使用<代码> BIG5或<代码> BIG5YHKSCs<代码>编码-尝试。 在任何情况下,接受马克的建议,并指向它
chardet
通常可以很好地检测所使用的编码,如果文件足够大并且编码正确,则为中文/日文/韩文-但是如果有人在文本编辑器中使用单字节字符集手动编辑文件,少数非法字符可能会导致其他99.9%字符的编码无法检测到
您可能希望对文件中的5行执行打印repr(line)
,然后将输出编辑到您的问题中
如果该文件不是机密文件,您可以将其下载
文件是在Windows上创建的吗?你是如何用Python阅读它的?(显示代码)
OP评论后更新:
记事本等不要试图猜测编码;“ANSI”是默认值。你必须告诉它该怎么做。您所称的欧元字符是编辑器使用环境的默认编码解码的原始字节“\x80”——通常怀疑为“cp1252”。不要使用这样的编辑器来编辑您的文件
早些时候,您谈论的是“最初的几个错误”。现在你说你总共有5个错误。请解释一下
如果文件确实几乎正确,那么您应该能够逐行解码文件,当您遇到这样的错误时,捕获它,打印错误消息,从消息中提取字节偏移量,打印repr(两个坏字节),然后继续。我非常感兴趣的是\x80
出现在两个字节中的哪一个。如果它根本没有出现,那么“欧式性格”就不是你的问题的一部分。请注意,\x80
可以有效地显示在gb18030文件中,但只能作为从\x81
到\xfe
的2字节序列的第2个字节
在你试图解决问题之前,最好先知道你的问题是什么。试图通过在“ANSI”模式下使用记事本等工具来修复它不是一个好主意
你一直在回避你是如何认为gb18030解码的结果是有意义的。特别是,我将仔细检查gbk失败但gb18030“起作用”的行——其中肯定有一些非常罕见的汉字,或者可能有一些非中文非ASCII字符
这里有一个更好的检查损坏的方法的建议:使用原始字节对每个文件进行解码(编码“替换”)
并将结果(编码为utf8)写入另一个文件。通过结果对错误进行计数。计数(u'\ufffd')
。查看输出文件,使用您认为gb18030解码有意义的内容。U+FFFD字符应显示为黑色菱形内的白色问号
如果您决定可以丢弃不可编码的片段,最简单的方法是raw\u bytes.decode(编码“忽略”)
进一步信息后更新
所有这些\\
都令人困惑。“获取字节”似乎涉及到repr(repr(bytes))
而不仅仅是repr(bytes)
。。。在互动
C1 C2 C1 C2 cb be 80 80 22 # `\x22` is the quote character
>>> '\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 sequence
u'\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 sequence
u'\u53f8"'
>>>
>>> '\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 sequence
u'\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 sequence
u'\ufffd\ufffdabcd'
>>>
codecs.open(file, encoding='gb18030', errors='replace')