解码ascii文件中的非ascii字符?

时间:2017-03-22 18:02:37

标签: python encoding decode

我正在解析一个ascii格式的文件,但在big5(Trad。中文)中包含非ascii字符。
有关详细信息,请参阅CISAC的CWR文件。

我试图不成功地解码非ascii字符。 这是一个示例行:

NWN000003930000016400507347 ^N&ÊÅ+/{^O

从第29位到第188位应以big5编码。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
import sys
import binascii
from chardet.universaldetector import UniversalDetector
from chardet import detect

with open("/path/to/file") as fd:
    line = fd.readline()
    while line:
        if line[0:3] == 'NWN':
            last_name = line[29:188]
            print last_name
            print detect(line)['encoding']
            print last_name.decode('big5')
        line = fd.readline()

但是,上面这行的结果是:

None
&岒+/{

以下一行:

NWN000000140000016300401453 ^N/õ<Dï.^O

甚至崩溃:

windows-1252
Traceback (most recent call last):
  File "test_big5.py", line 36, in <module>
print last_name.decode('big5')
UnicodeDecodeError: 'big5' codec can't decode bytes in position 1-2: illegal multibyte sequence

我也尝试过如下:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from codecs import EncodedFile

from_encoding = 'big5'
to_encoding = 'utf8'    
sys.stdout = EncodedFile(sys.stdout, from_encoding, to_encoding)

f = file("/path/to/file", "r")
str = f.read()
sys.stdout.write(str)

我附上了一个示例文件here

对我做错了什么的想法?

1 个答案:

答案 0 :(得分:0)

您应该能够使用big5编解码器读取文件。在尝试时,我得到了

>>> import codecs
>>> codecs.open('nwn.file', encoding="big5").read()
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/lib/python2.7/codecs.py", line 668, in read
        return self.reader.read(size)
UnicodeDecodeError: 'big5' codec can't decode bytes in position 1790-1791: illegal multibyte sequence

你文件中的行很长,所以我将它们读入一个列表(没有编解码器,只需在“rb”模式和readlines()中打开文件)并修剪掉空格。现在我可以将此列表用作可运行的示例。当我建议您以二进制模式读取文件中的数据时,这就是我所得到的。

test = [
b'NWN000003930000016400507347 \x0e&\xca\xc5+/{\x0f                    ZH\r\n'
b'NWN000003960000016400507347 \x0e&\xca\xc5+/{\x0f                    ZH\r\n'
b'NWN000005660000046800507347 \x0e&\xca\xc5+/{\x0f                    ZH\r\n'
b'NWN000016200000016400507347 \x0e&\xca\xc5+/{\x0f                    ZH\r\n'
b'NWN000025600000016400507347 \x0e&\xca\xc5+/{\x0f                    ZH\r\n'
b'NWN000000140000016300401453 \x0e/\xf5<D\xef.\x0f                    ZH\r\n' 
]

然后我逐行解码。我使用errors='strict'来查看正在发生的事情,而不是默认的replace。那些&岒+/{有点奇怪,但后来我不知道这个文件是什么。请注意,问号是最后一行。有非big8序列。此文件已损坏。

>>> for line in test:
...     print line.strip().decode('big5', errors='replace')
... 
NWN000003930000016400507347 &岒+/{                    ZH
NWN000003960000016400507347 &岒+/{                    ZH
NWN000005660000046800507347 &岒+/{                    ZH
NWN000016200000016400507347 &岒+/{                    ZH
NWN000025600000016400507347 &岒+/{                    ZH
NWN000000140000016300401453 /�D�                    ZH

如果您需要大部分数据,您可以像我的示例一样逐行解码并捕获该错误。