Python 3.9.2 无法删除滑稽字符“½”

can not delete the funny character "½" in Python 3.9.2

#下面是Python2.6.6版本删除搞笑字符“½”的步骤,效果很好

#-*- coding: utf-8 -*- 

import os,glob

funny=glob.glob('C:\A\Text\*')   #This folder has 10 files, so i use '*' for a loop

for h in funny:
    with open(r'%s' %h, 'r') as infile,open(r'%sN' %h, 'w') as outfile:
        data = infile.read()
        data = data.replace ("13½","13")
        data = data.decode("ascii", "ignore")
        outfile.write(data)
        infile.close()
        outfile.close()
        os.remove(h)
        os.rename(r'%sN' %h,r'%s' %h)

但是现在我们升级到3.9.2版本,还是不行,报错信息如下:

Traceback (most recent call last): File "C:/A/test.py", line 10, in data = infile.read() File "C:\Program Files\Python39\lib\encodings\cp1252.py", line 23, in decode return codecs.charmap_decode(input,self.errors,decoding_table)[0] UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 10871: character maps to

我搜索了很多,在新版本中没有 replace 函数带有那个“½”,有什么想法吗?

Python 3 需要知道输入文件的编码。根据回溯,它似乎默认为 cp1252,但显然这是不正确的。我找不到这个字符实际映射到您问题中的字形的编码;有关 Python 3.6.8 支持的编码列表,请参阅 https://tripleee.github.io/8bit/#9d(披露:我自己的资源)。 (在 3.9 中应该没有太大变化。)

希望丢弃您不知道如何处理的数据通常只是一种绝望的解决方法,正确的解决方案是了解数据代表什么,如果确实有错误,则在源头修复错误,或者正确处理它而不是将其删除。

但这是对您的代码的修复。

for h in glob.glob(r'C:\A\Text\*'):
    dest = '%sN' % h
    with open(h, 'r', encoding='latin-1') as infile, open(dest, 'w', encoding='latin-1') as outfile:
        for line in infile:
            line = line.replace("13\x9d", "13")
            outfile.write(line)
    os.remove(h)
    os.rename(dest, h)

此处的 Latin-1 编码可能不完全正确,但只要您使用相同的编码进行读写,并且所有字符代码都在该编码中定义(因为它们方便地使用 Latin- 1) 结果应该是你所期望的。

我还重构为一次读取一行,而不是将整个文件拖入内存;如果你有足够的 RAM,那应该无关紧要,但如果你可能有大文件,这也应该提高健壮性。如果这些文件不是真正的文本文件,也许可以回滚该更改(但无论如何您可能会遇到不同的问题)。