как указать расширенный 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!')
.
как только вы станете просветленными в этом вопросе, у вас не будет проблем с решением вашей проблемы. Вам просто нужно решить, какой компонент в программном обеспечении принимает кодировку 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"