【问题标题】:Unicode-escaped file processing errorUnicode 转义文件处理错误
【发布时间】:2017-01-10 06:57:23
【问题描述】:

我有一个原始文本文件,仅包含以下行,没有换行符:

Q853 \u0410\u043D\u0434\u0440\u0435\u0439 \u0410\u0440\u0441\u0435\u043D\u044C\u0435\u0432\u0438\u0447 \u0422\u0430\u0440\u043A\u043E\u0432\u0441\u043A\u0438\u0439

如上所示,字符被转义,这意味着\u05E9 实际上是一个反斜杠,后跟 5 个字母数字字符(而不是 Unicode 字符)。我正在尝试使用以下代码解码文件:

import codecs

with codecs.open("wikidata-terms20.nt", 'r', encoding='unicode_escape') as input:
    with open("wikidata-terms3.nt", "w") as output:
        for line in input:
            output.write(line)

此处无法使用print,请参阅 cmets。

运行它给我以下错误:

Traceback (most recent call last):
  File "terms2.py", line 5, in <module>
    for line in input:
  File "C:\Program Files\Python35\lib\codecs.py", line 711, in __next__
    return next(self.reader)
  File "C:\Program Files\Python35\lib\codecs.py", line 642, in __next__
    line = self.readline()
  File "C:\Program Files\Python35\lib\codecs.py", line 555, in readline
    data = self.read(readsize, firstline=True)
  File "C:\Program Files\Python35\lib\codecs.py", line 501, in read
newchars, decodedbytes = self.decode(data, self.errors)
UnicodeDecodeError: 'unicodeescape' codec can't decode bytes in position 67-71: truncated \uXXXX escape

发生了什么事?

我在 Windows 8.1 上运行 Python 3.5.1,代码似乎适用于大多数其他 Unicode 字符(这一行是导致崩溃的第一行)。

查看原始问题的编辑历史记录。

【问题讨论】:

  • 请验证您是否收到此处的数据错误。使用print(line) 代替流程行注释,我没有收到任何错误。
  • 导致错误的第一行是Q501 \u05E9\u05D0\u05E8\u05DC \u05D1\u05D5\u05D3\u05DC\u05E8,如果是尾部则解码第一个字符。但是 U+05E9 似乎是有效的 Unicode。
  • 这是打印的问题。请注意错误如何提到编码为 cp850。见Python, Unicode, and the Windows console
  • 使用 python 2.7 在我的 Windows 7 上复制。现在将对其进行调试。
  • 我不完全理解这个问题,但似乎找到了解决方法。看我的回答。

标签: python python-3.x unicode python-unicode


【解决方案1】:

解码器读取的数据似乎在字符#72(基于 0 的字符 #71)处(之后)被截断。这显然与this bug 有关。

以下代码产生与您的示例相同的错误:

open("wikidata-terms20.nt", 'r').readline()
open("wikidata-terms20.nt", 'r').readline(72)

将 readline 大小增加到输入的实际大小之上或将其设置为 -1 可消除错误:

open("wikidata-terms20.nt", 'r').readline(1000)
open("wikidata-terms20.nt", 'r').readline(-1)

显然,for line in input:readline() 获取要解码的行,有效地将要解码的数据截断为 72 个字符。

所以这里有几个解决方法:

解决方法 1:

import codecs

with open("wikidata-terms20.nt", 'r') as input:
    with open("wikidata-terms3.nt", "w") as output:
        for line in input:
            output.write(codecs.decode(line, 'unicode_escape'))

解决方法 2:

import codecs

with codecs.open("wikidata-terms20.nt", 'r', encoding='unicode_escape') as input:
    with open("wikidata-terms3.nt", "w") as output:
        for line in input.readlines():
            output.write(line)

【讨论】:

  • 谢谢,效果很好!旁注,我必须指定 encoding='utf-8' 才能使 output.write 行不失败。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-12
  • 1970-01-01
  • 1970-01-01
  • 2010-11-03
  • 2013-05-13
  • 1970-01-01
  • 2018-04-21
相关资源
最近更新 更多