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,那应该无关紧要,但如果你可能有大文件,这也应该提高健壮性。如果这些文件不是真正的文本文件,也许可以回滚该更改(但无论如何您可能会遇到不同的问题)。
#下面是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,那应该无关紧要,但如果你可能有大文件,这也应该提高健壮性。如果这些文件不是真正的文本文件,也许可以回滚该更改(但无论如何您可能会遇到不同的问题)。