如何在python magic编码说明符行中指定扩展ascii(即范围(256))?

2024-05-13 21:39:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用mako模板生成专门的配置文件。其中一些文件包含扩展的ASCII字符(>;127),但mako choke说,当我使用以下字符时,这些字符超出了范围:

## -*- coding: ascii -*-

所以我想知道是否有这样的事情:

## -*- coding: eascii -*-

我可以用它来表示范围(128256)字符。

编辑:

以下是文件中违规部分的转储:

000001b0  39 c0 c1 c2 c3 c4 c5 c6  c7 c8 c9 ca cb cc cd ce  |9...............|
000001c0  cf d0 d1 d2 d3 d4 d5 d6  d7 d8 d9 da db dc dd de  |................|
000001d0  df e0 e1 e2 e3 e4 e5 e6  e7 e8 e9 ea eb ec ed ee  |................|
000001e0  ef f0 f1 f2 f3 f4 f5 f6  f7 f8 f9 fa fb fc fd fe  |................|
000001f0  ff 5d 2b 28 27 73 29 3f  22 0a 20 20 20 20 20 20  |.]+('s)?".      |
00000200  20 20 74 6f 6b 65 6e 3a  20 57 4f 52 44 20 20 20  |  token: WORD   |
00000210  20 20 22 5b 41 2d 5a 61  2d 7a 30 2d 39 c0 c1 c2  |  "[A-Za-z0-9...|
00000220  c3 c4 c5 c6 c7 c8 c9 ca  cb cc cd ce cf d0 d1 d2  |................|
00000230  d3 d4 d5 d6 d7 d8 d9 da  db dc dd de df e0 e1 e2  |................|
00000240  e3 e4 e5 e6 e7 e8 e9 ea  eb ec ed ee ef f0 f1 f2  |................|
00000250  f3 f4 f5 f6 f7 f8 f9 fa  fb fc fd fe ff 5d 2b 28  |.............]+(|

mako抱怨的第一个字符是000001b4。如果我删除这个部分,一切正常。在插入该部分后,mako抱怨道:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 19: ordinal not in range(128)

无论我在magic comment行中使用ascii还是拉丁语-1,都是同样的抱怨。

谢谢!

格雷格


Tags: 文件makoascii字符c2c1codingc3
3条回答

试试看

## -*- coding: UTF-8 -*-

或者

## -*- coding: latin-1 -*-

或者

## -*- coding: cp1252 -*-

取决于你真正需要什么。最后两个类似,除了:

The Windows-1252 codepage coincides with ISO-8859-1 for all codes except the range 128 to 159 (hex 80 to 9F), where the little-used C1 controls are replaced with additional characters. Windows-28591 is the actual ISO-8859-1 codepage.

其中ISO-8859-1latin-1的正式名称。

简短回答

使用cp437作为一些复古DOS乐趣的编码。所有大于或等于32十进制的字节值(127除外)都映射到此编码中的可显示字符。然后使用cp037作为一个真正的trippy时间的编码。然后扪心自问,如果其中任何一个是“正确的”,你怎么知道它们中的哪一个是“正确的”。

长答案

你必须忘记一些东西:字节值和字符的绝对等价性。

如今,许多基本的文本编辑器和调试工具,以及Python语言规范,都意味着字节和字符之间的绝对等价性,而实际上根本不存在这种等价性。74 6f 6b 65 6e不是“令牌”。只有对于与ASCII兼容的字符编码,此对应才有效。在EBCDIC中,“token”对应于字节值a3 96 92 85 95

因此,尽管Python 2.6解释器很高兴地将'text' == u'text'计算为True,但它不应该这样做,因为在ASCII或兼容编码的假设下,它们只是等价的,即使这样,也不应该认为它们是等价的。(至少'\xfd' == u'\xfd'False,并为您提供尝试警告。)Python 3.1将'text' == b'text'计算为False。但是,即使解释器接受这个表达式,也意味着字节值和字符的绝对等价性,因为表达式b'text'被认为是“解释器将ASCII编码应用于'text'时获得的字节字符串”。

据我所知,目前广泛使用的每一种编程语言在其设计中都隐含着ASCII或ISO-8859-1(拉丁语-1)字符编码。在C中,char数据类型实际上是一个字节。我看到一个Java 1.4vm,其中构造函数java.lang.String(byte[] data)采用ISO-8859-1编码。大多数编译器和解释器假定源代码是ASCII或ISO-8859-1编码(有些允许您更改)。在Java中,字符串长度实际上是UTF-16代码单位长度,这对于字符U+10000和更高的字符可能是错误的。在Unix中,文件名是根据终端设置解释的字节字符串,允许您open('a\x08b', 'w').write('Say my name!')

因此,我们都接受过训练,并被我们学会信任的工具所制约,相信“A”0x41。但它不是。“A”是一个字符,0x41是一个字节,它们根本不相等。

一旦你在这一点上开悟了,你就不难解决你的问题。您只需确定软件中的哪个组件正在为这些字节值假定ASCII编码,以及如何更改该行为或确保出现不同的字节值。

注:“扩展ASCII”和“ANSI字符集”这两个词用词不当。

试着用批判的眼光审视你的数据:

000001b0 39c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce| 9……………|
000001c0cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de| |
000001d0数据框e0 e1 e2 e3 e4 e6 e7 e8 e9 ea eb ec ed ee| |
000001e0ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe| |
000001f0ff5d 2b 28 27 73 29 3f 22 0a 20 20 20 20 20 20 |.]+('s?“)。|
00000200 20 74 6f 6b 65 6e 3a 20 57 4f 52 44 20 20 20 |代币:WORD |
00000210 20 22 5b 41二维5a 61二维7a 30二维39c0 c1 c2|“[A-Za-z0-9…|
00000220c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2| 00000230d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2| |
00000240e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2| |
00000250f3-f4-f5-f6-f7-f8-f9-fa-fb-fc-fd-fe-ff5d-2b-28 |……………]+(|)

粗体字是两个字节(每个字节从0xc0到0xff都包括在内)。您似乎有一个二进制文件(可能是编译的regex的转储文件),而不是文本文件。我建议您将其作为二进制文件读取,而不是将其粘贴到Python源文件中。您还应该阅读mako文档以了解它的期望值。

查看转储文件的文本部分后更新:您很可能可以用仅限ASCII的regex来表示,例如,您将有一行包含

token: WORD "[A-Za-z0-9\xc0-\xff]+(etc)etc"

相关问题 更多 >