我正在使用mako模板来生成专门的配置文件。其中一些文件包含扩展的ASCII字符(>127),但当我使用以下命令时,mako表示字符超出范围:
## -*- coding: ascii -*-所以我想知道是不是有这样的东西:
## -*- coding: eascii -*-我可以使用的范围是(128,256)个字符。
编辑:
下面是文件中有问题的部分的转储:
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)这是同样的抱怨,无论我使用'ascii‘或’拉丁语-1‘在魔术的评论行。
谢谢!
格雷格
发布于 2011-07-28 07:03:02
Short answer
使用cp437作为一些复古DOS乐趣的编码。除127外,所有大于或等于32个十进制的字节值都映射到此编码中的可显示字符。然后使用cp037作为真正的trippy时间的编码。然后问问你自己,你如何真正知道这两个中的哪一个是“正确的”。
Long answer
有一件事你必须忘记:字节值和字符的绝对等价性。
当今许多基本的文本编辑器和调试工具,以及Python语言规范,都暗示着字节和字符之间的绝对等价性,而实际上并不存在。74 6f 6b 65 6e 是 "token“,这是不正确的。只有对于兼容ASCII的字符编码,此对应关系才有效。在今天仍然很常见的EBCDIC中,"token“对应于字节值a3 96 92 85 95。
因此,虽然Python2.6解释器愉快地将'text' == u'text'计算为True,但它不应该这样做,因为它们只有在ASCII码或兼容编码的假设下才是等价的,即使这样,也不应该认为它们是相等的。(至少'\xfd' == u'\xfd'是False,它会在你尝试时给你一个警告。)Python3.1将'text' == b'text'评估为False。但是,即使解释器接受这个表达式,也意味着字节值和字符的绝对等价性,因为解释器将表达式b'text'理解为“对'text'应用ASCII码时得到的字节串”。
据我所知,今天广泛使用的每一种编程语言都在其设计中隐含地使用了ASCII或ISO-8859-1 (拉丁语-1)字符编码。在C中,char数据类型实际上是一个字节。我见过一个Java1.4VM,其中构造函数java.lang.String(byte[] data)采用了ISO-8859-1编码。大多数编译器和解释器假定源代码采用ASCII或ISO-8859-1编码(有些允许您更改)。在Java语言中,字符串长度实际上是UTF16代码单元的长度,这对于U+10000及以上的字符来说无疑是错误的。在Unix中,文件名是根据终端设置解释的字节字符串,允许您open('a\x08b', 'w').write('Say my name!')。
因此,我们都已经被我们学会信任的工具训练和调节,相信'A‘是 0x41。但事实并非如此。'A‘是一个字符,0x41是一个字节,它们根本不相等。
一旦你对这一点有了认识,你就会毫不费力地解决你的问题。您只需决定软件中的哪个组件对这些字节值采用ASCII编码,以及如何更改该行为或确保出现不同的字节值。
PS:“扩展ASCII”和"ANSI字符集“这两个短语用词不当。
发布于 2011-07-28 04:03:09
试一试
## -*- coding: UTF-8 -*-或
## -*- coding: latin-1 -*-或
## -*- coding: cp1252 -*-取决于你真正需要的是什么。后两个是相似的,除了:
除了128到159 (十六进制80到9F)之外,所有代码的
-1252代码页都与ISO-8859-1一致,其中很少使用的C1控件被替换为其他字符。Windows-28591是实际的ISO-8859-1代码页。
其中ISO-8859-1是latin-1的正式名称。
发布于 2011-07-28 10:11:14
试着用批判性的眼光检查你的数据:
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 |.]+('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 ed ee ef f0 f1 f2 |................|
00000250 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd ff 5d 2b 28 |.............]+(|
粗体的内容是两个批次(每个字节从0xc0到0xff,包括0xc0和0xff)。您似乎有一个二进制文件(可能是已编译的正则表达式的转储),而不是一个文本文件。我建议您将其作为二进制文件读取,而不是将其粘贴到Python源文件中。您还应该阅读mako文档以了解它所期望的内容。
在查看转储文件的文本部分后更新:您可以使用仅限ASCII码的正则表达式来表达这一点,例如,您可以使用包含以下内容的行
token: WORD "[A-Za-z0-9\xc0-\xff]+(etc)etc"https://stackoverflow.com/questions/6850486
复制相似问题