当前位置: 首页 > 面试题库 >

Python汉字编码错误

权韬
2023-03-14
问题内容

我是一个初学者,在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在特定语言中是有意义的。用latin1aka解码时,Universe中的每个文件都将通过第一个测试iso_8859_1。东亚语言中的许多文件都通过进行了第一个测试gb18030,因为大多数常用的中文,日文和韩文字符是使用相同的两字节序列块进行编码的。您完成了第二次测试的多少?

不要在IDE或文本编辑器中查看数据。在网络浏览器中查看它;他们通常可以更好地检测编码。

您怎么知道它是欧元字符?通过查看使用哪种编码对原始字节进行解码的文本编辑器的屏幕?cp1252?

您怎么知道它包含汉字?您确定不是日语吗?韩国人吗 你从哪里得到的?

在香港,台湾(可能是澳门)以及大陆以外的其他地方创建的中文文件会使用big5big5_hkscs编码-尝试这样做。

无论如何,请听取马克的建议并指向chardet它;chardet如果文件足够大并且已正确编码中文/日文/韩文,则通常可以很好地检测所使用的编码-
但是,如果有人使用单字节字符集在文本编辑器中手动编辑了文件,则有些非法字符可能导致无法检测到其他99.9%字符使用的编码。

您可能想对print repr(line)文件说5行,然后将输出编辑到您的问题中。

如果文件不是机密文件,则可能希望将其下载

是在Windows上创建的文件吗?您如何用Python阅读?(显示代码)

OP评论后更新:

记事本等不要试图猜测编码;默认值为“ ANSI”。您必须告诉它该怎么做。您所说的欧元字符是由编辑器使用您环境的默认编码解码的原始字节“ \
x80”,通常可疑的字符为“ cp1252”。不要使用这样的编辑器来编辑文件。

之前您在谈论“前几个错误”。现在,您说总共有5个错误。请解释。

如果文件确实几乎是正确的gb18030,则应该能够逐行解码文件,并且当出现此类错误时,将其捕获,打印错误消息,从消息中提取字节偏移,然后打印repr(two_bad_bytes)
,并继续前进。我对\x80出现的两个字节中的哪个非常感兴趣。如果根本没有出现,则“欧洲字符”不属于您的问题。请注意,\x80可以在GB18030文件有效出现,但只有与开始的2字节序列的第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(您将获得print repr(bytes)隐式repr())或(不会获得隐式repr())。

空格:我想您的意思'\xf8\xf8'.decode('gb18030')是将其解释为某种全角空格,并且通过使用某些无法命名的查看器软件进行目视检查来进行解释。那是对的吗?

实际上,'\xf8\xf8'.decode('gb18030')-> u'\e28b'。U + E28B位于Unicode
PUA(专用区域)中。“空白”可能意味着查看器软件毫无疑问没有使用的字体中的U + E28B字形。

也许文件的来源是故意使用PUA来处理不在标准gb18030中的字符,用于注释或用于传输伪秘密信息的。如果是这样,你需要求助于解码手鼓,俄罗斯最近研究的一个分支这里报告。

备选方案:cp939-HKSCS理论。根据香港政府的说法,HKSCS big5代码FE57曾经映射到U + E28B,但现在映射到U + 28804。

“ euro”:您说“”“由于数据我无法共享整行,但是我所说的欧元字符位于:\ xcb \ xbe \ x80 \ x80”
[我假设a\是从一开始就省略了,并且"是字面意义]。当出现“欧洲字符”时,它总是位于不需要的同一列中,因此我希望只使用“忽略”。不幸的是,由于“
euro char”正好在文件中的引号旁边,因此有时“忽略”会同时删除欧元字符和引号,这给csv模块确定列“”带来了问题”

如果您可以显示这些\x80字节相对于引号和汉字的显示方式,将大有帮助-仅显示十六进制即可保持可读性,并隐藏机密数据(例如,使用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 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"'
>>>

尤里卡: -有时失去引号字符的可能原因-

似乎在gb18030解码器的替换/忽略机制中存在错误:\x80不是有效的gb18030前导字节;当检测到解码器时,解码器应尝试与NEXT字节重新同步。但是,它似乎忽略了\x80AND和以下字节:

>>> '\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'
>>>


 类似资料:
  • 问题内容: 我正在通过对象从轴Web服务接收字符串。因为我没有得到我期望的字符串,所以我通过将字符串转换为字节进行了检查,然后在hexa中得到了C3A4C2 BDC2A0 C3A5C2 A5C2BD C3A5C2 90C297,当我期望使用E4BDA0 E5A5BD E59097时,实际上在UTF- 8。 有什么想法会导致您好吗成为C3A4C2 BDC2A0 C3A5C2 A5C2BD C3A5C

  • 问题内容: 我正在处理python-lastfm库返回的unicode字符串。 我假设在途中某个地方,该库获取了错误的编码,并返回了可能包含无效字符的unicode字符串。 例如,我期望变量a中的原始字符串为“G​​lück” \ xfc是转义值252,它对应于latin1编码的“ü”。它以某种方式以python无法自行处理的方式嵌入到unicode字符串中。 如何将其转换回包含原始“Glück”

  • 问题内容: 我不确定要如何处理此错误。我认为这与需要添加.encode(’utf-8’)有关。但是我不确定这是否是我需要做的,也不是应该在哪里应用。 错误是: 这是我的python脚本的基础。 问题答案: Python 2.x CSV库已损坏。您有三个选择。按照复杂度的顺序: 编辑:请参见下文 使用固定库 https://github.com/jdunck/python-unicodecsv( )

  • 本文向大家介绍escape编码与unescape解码汉字出现乱码的解决方法,包括了escape编码与unescape解码汉字出现乱码的解决方法的使用技巧和注意事项,需要的朋友参考一下 今天的项目中遇到需要用javascript的escape编码汉字再用unescape解码的情况,测试代码段的时候出现了乱码的情况。 具体情况如下: 首先,用EditPlus打开测试页面test.html,编辑如下ht

  • 本文向大家介绍php输出全部gb2312编码内的汉字方法,包括了php输出全部gb2312编码内的汉字方法的使用技巧和注意事项,需要的朋友参考一下 php输出全部gb2312编码内的汉字,$area表示分区,$pos表示分区内所在位置。 以上这篇php输出全部gb2312编码内的汉字方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持呐喊教程。

  • 问题内容: 我是python3的新手,来自python2,并且我对unicode基本概念有些困惑。我读了一些不错的文章,使事情变得更加清楚,但是我看到python 3上有2种方法可以处理编码和解码,而且我不确定要使用哪种方法。 因此,Python 3中的想法是,每个字符串都是unicode,并且可以按字节进行编码和存储,或者可以再次解码回unicode字符串。 但是有两种方法可以做到: 会生成,但