Python utf-8 转换为 cp1252

Python utf-8 conversion to cp1252

提问人:Mirek Hotový 提问时间:4/1/2022 最后编辑:Mirek Hotový 更新时间:4/2/2022 访问量:2425

问:

我已经有代码来遍历深层文件结构中的所有文件,其中所有文件都是 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")
Python 编码 UTF-8 ANSI CP1252

评论

0赞 Caique C Pereira 4/1/2022
关于第一个示例:您不能在编码系统 (utf-8) 中对文本进行编码,而使用另一个编码系统 (cp1252) 进行解码。尝试示例 2 和 3 时会出现什么错误?您确定您的文件是使用 utf-8 编写的吗?
0赞 lenz 4/2/2022
为什么要用 Ø 代替 Ř?这当然不是任何形式的“标准替换”,而是一个数据错误——字符因猜测编码错误而误解。
0赞 JosefZ 4/2/2022
Řř=Øø是一个实例化的 Mojibake 案例:返回 @lenz ...'Řř'.encode( 'cp1250').decode( '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 代码点。