在 UTF-8 文件中错误地处理 ASCII 编码的不间断 space?

Handle erroneously ASCII-encoded non-breaking space in UTF-8 file?

我有一个 Python 2.7 脚本,它从其他各种来源导出的 CSV 文件中导入数据。

作为导入过程的一部分,我有一个小函数可以为文件建立正确的字符编码。然后我打开文件并循环使用以下行:

with io.open(filename, "r", encoding=file_encoding) as input_file:
    for raw_line in input_file:
        cleaned_line = raw_line.replace('\x00', '').replace(u"\ufeff", "").encode('utf-8')
        # do stuff

来自此来源的文件通常以 UTF-8(带 BOM)形式出现,我检测到编码 'utf-8-sig' 并使用它打开文件。

我遇到的问题是我的一个数据源 returns 一个文件似乎有编码错误。文件的其余部分(大约 27k 行 CSV 数据)和往常一样都是正确的,但是有一行失败了。

相关行失败并出现此错误(在 for raw_line in input_file 行):

UnicodeDecodeError: 'utf8' codec can't decode byte 0xa0 in position 1709: invalid start byte

该行有几个不间断的空格字符,这些字符被编码为具有值 'A0' 的单个字节,而不是具有 'C2 A0'.

的 2 个字节

我已经在逐行地对其他问题进行轻微清理,正如您在循环顶部的 "cleaned_line" 行中看到的那样(我不喜欢逐行执行此操作,但使用文件我知道我还没有找到更好的方法)。但是,代码在我到达那里之前就失败了。

是否有 correct/nice 方法来处理这个特定问题?我以为我已经解决了整个编码问题。

您可以告诉 Python 忽略解码错误,或用占位符替换错误字节。

errors 设置为 'ignore' 以忽略 A0 字节:

with io.open(filename, "r", encoding=file_encoding, errors='ignore') as input_file:

'replace' 将它们替换为 U+FFFD REPLACEMENT CHARACTER:

with io.open(filename, "r", encoding=file_encoding, errors='replace') as input_file:

UTF-8 是一种自校正编码;字节要么始终是多字节代码点的一部分,要么可以直接解码为 ASCII,因此忽略不可解码的字节是相对安全的。

您可以进行编码 'translit/long' 以将 utf-8 规范化为 table 字符串图表,需要先导入 translitcodec。