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

Python中的UnicodeDecodeError在读取文件时如何忽略错误并跳至下一行?

叶鸿振
2023-03-14
问题内容

我必须将文本文件读入Python。文件编码为:

file -bi test.csv 
text/plain; charset=us-ascii

这是一个第三方文件,我每天都会得到一个新文件,所以我宁愿不更改它。该文件具有非ASCII字符,例如Ö。我需要使用python读取行,并且我可以忽略掉具有非ascii字符的行。

我的问题是,当我用Python读取文件时,到达非ASCII字符所在的行时出现UnicodeDecodeError,而我无法读取文件的其余部分。

有没有办法避免这种情况。如果我尝试这样做:

fileHandle = codecs.open("test.csv", encoding='utf-8');
try:
    for line in companiesFile:
        print(line, end="");
except UnicodeDecodeError:
    pass;

然后到达错误时,for循环结束,而我无法读取文件的其余部分。我想跳过导致错误的行,然后继续。如果可能,我宁愿不对输入文件进行任何更改。

有什么办法吗?非常感谢你。


问题答案:

您的文件似乎未使用UTF-8编码。打开文件时使用正确的编解码器很重要。


可以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)]

例如

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如果“行”足够大,则可能导致异常。



 类似资料:
  • 问题内容: 在Python中,我刚刚阅读了一个文本文件中的一行,并且我想知道如何编写代码以忽略该行开头带有#的注释。 我认为应该是这样的: 但是我是Python的新手,我不知道语法 问题答案: 您可以使用startswith() 例如

  • 问题内容: 我有一些代码可以从文件中读取行,我想识别行何时开始或fisrt字符(非空白)为’ ‘并忽略它,因此在while语句中添加如下内容 我有类似的东西: 如何完成代码? 问题答案:

  • 我正在运行一个程序,可以处理30000个类似的文件。他们中的一些人正在停止并产生这个错误...

  • 现在,我想存储一个如下所示的文本文件: 1个苹果 香蕉2根 3橙色 4只山猫 5卡布奇诺 以此类推到数据结构中。最好的方法是以某种方式将int映射到字符串,还是我应该制作一个数组列表?当我存储单词本身时,我应该忽略int和任何空格,只保留单词本身。在行中读取时如何忽略int?这是我现在拼凑的代码: } 提前感谢您的帮助!!

  • 问题内容: 我有一些代码可以读取名称文件并创建列表: 每个名称用换行符分隔,如下所示: 我想忽略仅包含空格的任何行。我知道我可以通过以下方式来实现:创建一个循环并检查读取的每一行,然后将其添加到列表(如果不是空白的话)。 我只是想知道是否还有更Pythonic的方法? 问题答案: 我将堆栈生成器表达式: 现在,是所有非空白行。这将使您不必在线路上两次打电话。如果需要行列表,则可以执行以下操作: 您

  • 我目前正在学习Python,遇到了以下错误: 这是我的代码: 为什么会出现这种情况?