删除所有无法在Python中解码的字符

时间:2015-06-18 18:11:34

标签: python encoding

我尝试使用xml.etree.ElementTree模块使用Python脚本解析html文件。根据标题,字符集应为UTF-8。但文件中有一个奇怪的字符。因此,解析器无法解析它。我在Notepad ++中打开文件以查看字符FS。我尝试用几种编码打开它,但我找不到正确的。

由于我要解析许多文件,我想知道如何删除所有无法解码的字节。有解决方案吗?

1 个答案:

答案 0 :(得分:7)

  

我想知道如何删除所有无法解码的字节。有解决方案吗?

这很简单:

with open('filename', 'r', encoding='utf8', errors='ignore') as f:
    ...

errors='ignore'告诉Python删除无法识别的字符。它也可以传递给bytes.decode()和其他大多数采用encoding参数的地方。

由于这会将字节解码为unicode,因此可能不适合想要使用字节的XML解析器。在这种情况下,您应该将数据写回磁盘(例如使用shutil.copyfileobj()),然后以'rb'模式重新打开。

在Python 2中,内置open()的这些参数不存在,但您可以使用io.open()。或者,您可以在阅读后将8位字符串解码为unicode字符串,但在我看来这更容易出错。

但事实证明OP没有无效的UTF-8。 OP具有有效的UTF-8,恰好包含控制字符。过滤掉控制字符有点烦人,因为你必须通过这样的函数运行它们,这意味着你不能只使用copyfileobj()

import unicodedata

def strip_control_chars(data: str) -> str:
    return ''.join(c for c in data if unicodedata.category(c) != 'Cc')

Cc是“其他,控制角色的Unicode类别,正如所描述的那样on the Unicode website。为了包含更广泛的”坏角色“,我们可以删除整个”其他“类别(主要包含无用的东西)反正):

def strip_control_chars(data: str) -> str:
    return ''.join(c for c in data if not unicodedata.category(c).startswith('C'))

这会过滤掉换行符,所以最好一次处理一行文件并在最后添加换行符。

原则上,我们可以创建codec来逐步执行此操作,然后我们可以使用copyfileobj(),但这就像使用大锤拍打苍蝇一样。< / p>