1

我想向我的学生展示以 macroman/latin1 格式打开一个编码为 latin1/macroman [resp.] 的文件的结果:

>>> s = u"Tout condamné à mort aura la tête tranchée."
>>> print s.encode("latin1").decode("macroman")
Tout condamnÈ ‡ mort aura la tÍte tranchÈe.
>>> print s.encode("macroman").decode("latin1")
Tout condamn  mort aura la tte tranche.

但我对第二次转换没有显示任何可见的非 ASCII 字符这一事实感到困惑。不是 macroman 和 latin1 都意味着字节 <-> 字符双射吗?

注意:这与 Python 无关,因为我可以使用文本编辑器重现该行为。

4

1 回答 1

2

“Latin1”是一个模糊的术语,可能指的是 ISO Latin 1 (ISO 8859-1) 或 Windows Latin 1 (windows-1252)。不同之处在于,在 ISO Latin 1 中,字节 0x80 到 0x9F 被指定为控制字符(很少使用),而在 Windows Latin 1 中,它们大部分被定义为图形字符(标点符号和一些非 Ascii 拉丁字母)和一些未定义。

例如,当您将字母“é”和 Latin1 编码(在任一 Latin1 编码中)时,您将得到字节 0xE9。如果您随后将此字节解释为 MacRoman 编码,就像您正在做的那样,您会得到“È”字符。这就是为什么你会得到“condamnÈ”。

但是,如果您将字母“é”作为 MacRoman 编码,则它是 0x8E。当将此字节解释为 Latin1 数据时,Latin1 编码不同。在 ISO Latin 1 中,它是控制字符 SINGLE SHIFT TWO (U+008E);在 Windows Latin 1 中,它是带有 CARON 的“Ž”拉丁大写字母 Z (U+017D)。显然,您的代码将 Latin1 视为 ISO Latin 1。由于 U+008E 在大多数程序中通常没有分配给它的含义,因此它通常在渲染中被忽略,但在这种情况下显然显示为空格。

其他情况类似:MacRoman “à” 是 0x88,MacRoman “ê” 是 0x90,都属于 ISO 8859-1 中的控制字符。

于 2013-09-10T17:06:44.133 回答