您的文件似乎没有使用 UTF-8 编码。打开文件时使用正确的编解码器非常重要。
You can tell open() https://docs.python.org/3/library/functions.html#open如何处理解码错误,用errors
关键词:
errors是一个可选字符串,指定如何处理编码和解码错误 - 这不能在二进制模式下使用。有多种标准错误处理程序可用,尽管已注册的任何错误处理名称codecs.register_error()
也是有效的。标准名称是:
-
'strict'
提出一个ValueError
如果存在编码错误则异常。默认值为None
具有相同的效果。
-
'ignore'
忽略错误。请注意,忽略编码错误可能会导致数据丢失。
-
'replace'
导致在存在格式错误的数据的地方插入替换标记(例如“?”)。
-
'surrogateescape'
会将任何不正确的字节表示为 Unicode 专用使用区域中从 U+DC80 到 U+DCFF 的代码点。然后,当surrogateescape
写入数据时使用错误处理程序。这对于处理未知编码的文件很有用。
-
'xmlcharrefreplace'
仅在写入文件时受支持。编码不支持的字符将替换为适当的 XML 字符引用&#nnn;
.
-
'backslashreplace'
(也仅在写入时支持)用 Python 反斜杠转义序列替换不支持的字符。
使用除以下以外的任何其他方式打开文件'strict'
('ignore'
, 'replace'
等)然后将让您读取该文件而不会引发异常。
请注意,解码是按缓冲的数据块进行的,而不是按文本行进行。如果必须逐行检测错误,请使用surrogateescape
处理程序并测试代理范围内代码点读取的每一行:
import re
_surrogates = re.compile(r"[\uDC80-\uDCFF]")
def detect_decoding_errors_line(l, _s=_surrogates.finditer):
"""Return decoding errors in a line of text
Works with text lines decoded with the surrogateescape
error handler.
Returns a list of (pos, byte) tuples
"""
# DC80 - DCFF encode bad bytes 80-FF
return [(m.start(), bytes([ord(m.group()) - 0xDC00]))
for m in _s(l)]
E.g.
with open("test.csv", encoding="utf8", errors="surrogateescape") as f:
for i, line in enumerate(f, 1):
errors = detect_decoding_errors_line(line)
if errors:
print(f"Found errors on line {i}:")
for (col, b) in errors:
print(f" {col + 1:2d}: {b[0]:02x}")
请注意,并非所有解码错误都可以正常恢复。虽然 UTF-8 的设计在面对小错误时具有鲁棒性,但其他多字节编码(例如 UTF-16 和 UTF-32)无法应对丢失或额外的字节,这将影响行分隔符的准确度位于。上述方法可能会导致文件的其余部分被视为一长行。如果文件足够大,则可能会导致MemoryError
如果“线”足够大,则例外。