从文本文件中删除未知字符

2 投票
3 回答
8170 浏览
提问于 2025-04-16 07:36

我有很多文件,里面有我想用Python脚本处理的数据。

这些文件的编码方式我不太清楚,如果我用Notepad++打开它们,会发现里面有数字数据,但中间夹杂着很多“空字符”(在Notepad++中显示为黑底白字的NULL)。

为了处理这些文件,我用空字符\x00来分隔文件,只提取数字值,使用了以下脚本:

stripped_data=[]
for root,dirs,files in os.walk(PATH):
    for rawfile in files:
        (dirName, fileName)= os.path.split(rawfile)
        (fileBaseName, fileExtension)=os.path.splitext(fileName)
        h=open(os.path.join(root, rawfile),'r')
        line=h.read()
        for raw_value in line.split('\x00'):
            try:
                test=float(raw_value)
                stripped_data.append(raw_value.strip())
            except ValueError:  
                pass

不过,有时候文件里还会出现一些我不认识的字符(我发现这些字符总是在文件的最开头)——在Notepad++中,它们显示为'EOT'、'SUB'和'ETX'。这些字符似乎会干扰Python对文件的处理——文件在这些字符处就好像结束了一样,尽管在Notepad++中明显还有更多的数据。

我该如何在处理这些文件之前,先把所有非ASCII字符去掉呢?

3 个回答

1

file.read() 这个函数会一直读取文件,直到遇到文件结束符(EOF)。你提到它停止得太早了,你希望在遇到文件结束符时还能继续读取文件。确保在你读取完整个文件后再停止。你可以通过在遇到文件结束符时使用file.tell()来检查当前读取的位置,并在到达文件大小时停止(在读取之前先获取文件大小)。

因为这个过程比较复杂,你可以考虑使用file.next,这样可以逐字节地读取文件。

如果你想去掉非ASCII字符,可以使用一个白名单来指定哪些字符是可以的,或者检查读取的字节是否在你定义的范围内。比如说,如果这个字节在x30到x39之间(也就是数字),那么就保留它,或者把它存到某个地方,或者加到一个字符串里。你可以参考一下ASCII表

1

我不确定这个方法是否一定有效,但你可以试试在 codec 模块中使用输入输出的方法:

import codec

inFile = codec.open(<SAME ARGS AS 'OPEN'>, 'utf-8')
for line in inFile.readline():
    do_stuff()

你可以把 inFile 当作一个普通的文件对象来使用。

这个方法可能对你有帮助,也可能没有,但大概率会有用。

[编辑]

基本上,你需要把这行代码: h=open(os.path.join(root, rawfile),'r') 改成 h=open(os.path.join(root, rawfile),'r', 'utf-8')

5

你现在是以文本模式打开文件的。这意味着第一个 Ctrl-Z 字符会被当作文件结束的标志。你应该在打开文件时用 'rb' 代替 'r'。

撰写回答