как указать расширенный ascii (т. е. диапазон (256)) в строке спецификатора кодировки python magic?

Я использую шаблоны mako для создания специализированных файлов конфигурации. Некоторые из этих файлов содержат расширенные символы ASCII (>127), но Мако задыхается, говоря, что символы вне диапазона, когда я использую:

## -*- coding: ascii -*-

поэтому мне интересно, возможно, есть что-то вроде:

## -*- coding: eascii -*-

что я могу использовать, это будет нормально с диапазоном (128, 256) символов.

EDIT:

вот дамп оскорбительного раздела файла:

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  |.............]+(|

в первый символ, на который жалуется Мако, - 000001b4. Если я удалю этот раздел, Все будет хорошо. Вставив раздел, Мако жалуется:

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

это та же жалоба, использую ли я "ascii" или "latin-1" в строке комментария magic.

спасибо!

Грег

3 ответов


короткий ответ:

используйте cp437 в качестве кодировки для некоторых ретро DOS удовольствия. Все байтовые значения, большие или равные 32 decimal, за исключением 127, сопоставляются с отображаемыми символами в этой кодировке. Затем используйте cp037 для кодирования действительно трип время. А затем спросите себя, как вы действительно знаете, какой из них, если любой из них "правильный".

ответ

есть кое-что, что вы должны разучиться: абсолютная эквивалентность байтовых значений и символов.

многие основные текстовые редакторы и инструменты отладки сегодня, а также спецификация языка Python, подразумевают абсолютную эквивалентность между байтами и символами, когда на самом деле их нет. Это неправда, что 74 6f 6b 65 6e is "маркер". Только для ASCII-совместимых кодировок символов это переписка действительным. В EBCDIC, который все еще довольно распространен сегодня, "токен" соответствует значениям байтов a3 96 92 85 95.

Итак, в то время как интерпретатор Python 2.6 счастливо оценивает 'text' == u'text' as True, это не должно, потому что они являются только эквивалентно в предположении ASCII или совместимой кодировки, и даже тогда они не должны рассматриваться равной. (По крайней мере '\xfd' == u'\xfd' is False и получает предупреждение за попытку.) В Python 3.1 оценивает 'text' == b'text' as False. Но даже принятие этого выражения интерпретатором подразумевает абсолютное эквивалентность байтовых значений и символов, поскольку выражение b'text' принимается за " байт-строку, которую вы получаете, когда применяете кодировку ASCII к 'text'" переводчика.

насколько я знаю, каждый язык программирования, широко используемый сегодня, несет в себе неявное использование кодировки символов ASCII или ISO-8859-1 (Latin-1) где-то в своем дизайне. В с,char тип данных действительно байт. Я видел одну JAVA 1.4 VM, где конструктор 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!').

is 0x41. Но это не так. "A" - это символ, а 0x41-байт, и они просто не равны.

как только вы станете просветленными в этом вопросе, у вас не будет проблем с решением вашей проблемы. Вам просто нужно решить, какой компонент в программном обеспечении принимает кодировку ASCII для этих байтовых значений и как либо изменить это поведение, либо гарантировать, что вместо этого появятся другие байтовые значения.

PS: фразы "расширенный ASCII" и "набор символов ANSI" являются неправильное употребление.


попробовать

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

или

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

или

## -*- coding: cp1252 -*-

в зависимости от того, что вам действительно нужно. Последние два похожи, за исключением:

кодовая страница Windows-1252 совпадает с ISO-8859-1 для всех кодов, кроме диапазона от 128 до 159 (hex 80 до 9F), где мало используемые элементы управления C1 заменяются дополнительными символами. Windows-28591-это фактическая кодовая страница ISO-8859-1.

здесь ISO-8859-1 - это официальное название для latin-1.


попробуйте изучить ваши данные критическим взглядом:

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 | токен: 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 |................|
Ноль ноль ноль ноль ноль двести сорок 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 |.............]+(|

материал жирным шрифтом-два лота (каждый байт от 0xc0 до 0xff включительно). У вас, кажется, есть двоичный файл (возможно, дамп скомпилированных регулярных выражений), а не текстовый файл. Я предлагаю вам прочитать его как двоичный файл, а не вставлять его в исходный файл Python. Вы следует также прочитать документы mako, чтобы узнать, чего он ожидает.

обновление после просмотра текстовой части вашего дампа: вы вполне можете выразить это в ASCII-только regexes, например, у вас будет строка, содержащая

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