提问人:Mirek Hotový 提问时间:4/1/2022 最后编辑:Mirek Hotový 更新时间:4/2/2022 访问量:2425
Python utf-8 转换为 cp1252
Python utf-8 conversion to cp1252
问:
我已经有代码来遍历深层文件结构中的所有文件,其中所有文件都是 utf-8,需要转换为 c1252 又名 ANSI。
我需要获得与在任何严肃的文本编辑器中覆盖文件相同的简单结果......为什么会有损失?是的,有些字符标准地被不同的字符替换:Šš=Šš Čč=Èè Ťť=??Žž=Žž Ěě=Ìì Řř=Øø Ďď=Ïï Ňň=Òò Ůů=Ùù
但是由于一个简单的字符串转换,比如
>>> print("Šš Čč Ťť Žž Ěě Řř Ďď Ňň Ůů".encode("utf-8").decode("cp1252"))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Program Files\Python310\lib\encodings\cp1252.py", line 15, in decode
return codecs.charmap_decode(input,errors,decoding_table)
UnicodeDecodeError: 'charmap' codec can't decode byte 0x8d in position 8: character maps to <undefined>
...不起作用,我的机会是什么?我一整天都在这里和那里阅读了数十篇文章,但找不到可行的解决方案或理解这个 cp 转换 PITA 的地狱。发现即使是完整的函数和转换器,显然是为 Python 2 编写的,也无法正常工作。
也不起作用:
chcp 65001
Active code page: 65001
with open(fpath, mode="r", encoding="utf-8") as fd:
content = fd.read()
with open(fpath, mode="w", encoding="cp1252") as fd:
fd.write(content)
或
with open(fpath, mode="r", encoding="utf-8") as fd:
decoded = fd.decode("utf-8")
content = decoded.encode("cp1252")
答:
0赞
Mark Tolonen
4/1/2022
#1
你的第一个例子永远不会奏效。使用一种方案对 Unicode 字符串进行编码并解码为另一种方案是不正确的,但您可以使用生成文件的编码对文件或字节字符串进行解码,然后用另一种编码对其进行重新编码。但是,编码需要支持相同的 Unicode 码位。
UTF-8 支持对所有 Unicode 码位进行编码,而 CP1252 支持 <256,因此如果您采用这种方式,请不要指望您的文件包含相同的信息。
在解码(读取)文件和编码(写入)文件时可以使用一个参数。下面是提供的示例字符串中的丢失示例:errors
>>> s = "Šš Čč Ťť Žž Ěě Řř Ďď Ňň Ůů"
>>> s.encode('cp1252',errors='ignore').decode('cp1252')
'Šš Žž '
>>> s.encode('cp1252',errors='replace').decode('cp1252')
'Šš ?? ?? Žž ?? ?? ?? ?? ??'
也有非有损转换,但使用替换方案。请参阅 Python 编解码器文档中的错误处理程序。
因此,第二个示例可以通过提供参数来处理损失:errors
with open(fpath, mode="r", encoding="utf-8") as fd:
content = fd.read()
with open(fpath, mode="w", encoding="cp1252", errors='replace') as fd:
fd.write(content)
评论
0赞
Mirek Hotový
4/2/2022
我需要获得与在任何严肃的文本编辑器中覆盖文件相同的简单结果......为什么会有损失?是的,有些字符标准地被不同的字符替换:Šš=Šš Čč=Èè Ťť=??Žž=Žž Ěě=Ìì Řř=Øø Ďď=Ïï Ňň=Òò Ůů=Ùù 如何实现这一点?
1赞
Mark Tolonen
4/2/2022
@MirekHotový CP1252为单字节编码,1个字节==1个Unicode码位。单个字节只有 256 个值。有 1M+ Unicode 码位。您只能将支持的 Unicode 码位保存在 CP1252 编码文件中。UTF-8 是一种多字节编码,可以支持整个范围的 Unicode 代码点。
评论
Řř=Øø
是一个实例化的 Mojibake 案例:返回 @lenz ...'Řř'.encode( 'cp1250').decode( 'cp1252')
'Øø'