Если у вас есть проблема с символами / байтами, отличными от ASCII, распечатывать их на консоли, а затем копировать / вставлять в ваш вопрос, довольно бесполезно. То, что вы видите, довольно часто НЕ то, что вы получили. Вы должны использовать встроенную функцию repr()
[Python 3.x: ascii()
], чтобы показать ваши данные как можно более однозначно.
Сделайте это:
python -c "print repr(open('shiftjis.txt', 'rb').read())"
и скопируйте / вставьте результаты в свой вопрос.
Обратный инжиниринг ваших данных в ожидании просветления: кодовая страница Windows должна быть хорошим подозреваемым, с cp1252
самым обычным. Как показал @Mark Tolonen, cp1252
почти подходит, с одной ошибкой. Дальнейшие исследования показывают, что другие кодировки cp125x
вызывают 2, 3 или 5 ошибок. AFAIK только кодировки cp125x
будут отображать что-то, похожее на запятую (на самом деле U + 201A ОДНОКРАТНАЯ МАРКА ЦИТАТЫ U + 201A), на ведущий байт shift-jis \x82
. Я пришел к выводу, что нарушитель cp1252
, и что ошибка вызвана повреждением при транспортировке.
Другая возможность состоит в том, что исходная кодировка не shift-jis
, а ее расширенный набор cp932
от Microsoft, используемый в японской Windows. Однако проблемная последовательность '\x82@'
недопустима в cp932
. В любом случае, если файл (-ы), которые вы хотите обработать, были получены с японского компьютера с Windows, лучше использовать cp932
, чем shift-jis
.
Из вашего вопроса и вашего кода не очевидно, что вы хотите делать, и почему вы хотите делать это с байтовыми диапазонами, а не просто декодировать свои данные в Unicode. Я не использую pyparsing
, но весьма вероятно, что поддиапазоны, которыми вы его кормите, имеют неправильные формы.
Ниже приведен пример того, как вы можете токенизировать свой ввод, используя регулярные выражения. Обратите внимание, что синтаксический синтаксический анализ немного отличается (\0xff
вместо `\ xff 'в Python).
Код:
import re, unicodedata
input_bytes = '\x82s\x82\x88\x82\x89\x82\x93@\x82\x89\x82\x93@\x82@\x82\x93\x82\x88\x82\x89\x82\x86\x82\x94[\x82\x8a\x82\x89\x82\x93@\x82\x93\x82\x94\x82\x92\x82\x89\x82\x8e\x82\x87B'
p_ascii = r'[\x00-\x7f]'
p_hw_katakana = r'[\xa1-\xdf]' # half-width Katakana
p_jis208 = r'[\x81-\x9f\xe0-\xef][\x40-\x7e\x80-\xfc]'
p_bad = r'.' # anything else
kinds = ['jis208', 'ascii', 'hwk', 'bad']
re_matcher = re.compile("(" + ")|(".join([p_jis208, p_ascii, p_hw_katakana, p_bad]) + ")")
for mobj in re_matcher.finditer(input_bytes):
s = mobj.group()
us = s.decode('shift-jis', 'replace')
print ("%-6s %-9s %-10r U+%04X %s"
% (kinds[mobj.lastindex - 1], mobj.span(), s, ord(us), unicodedata.name(us, '<no name>'))
)
Выход:
jis208 (0, 2) '\x82s' U+FF34 FULLWIDTH LATIN CAPITAL LETTER T
jis208 (2, 4) '\x82\x88' U+FF48 FULLWIDTH LATIN SMALL LETTER H
jis208 (4, 6) '\x82\x89' U+FF49 FULLWIDTH LATIN SMALL LETTER I
jis208 (6, 8) '\x82\x93' U+FF53 FULLWIDTH LATIN SMALL LETTER S
ascii (8, 9) '@' U+0040 COMMERCIAL AT
jis208 (9, 11) '\x82\x89' U+FF49 FULLWIDTH LATIN SMALL LETTER I
jis208 (11, 13) '\x82\x93' U+FF53 FULLWIDTH LATIN SMALL LETTER S
ascii (13, 14) '@' U+0040 COMMERCIAL AT
jis208 (14, 16) '\x82@' U+FFFD REPLACEMENT CHARACTER
jis208 (16, 18) '\x82\x93' U+FF53 FULLWIDTH LATIN SMALL LETTER S
jis208 (18, 20) '\x82\x88' U+FF48 FULLWIDTH LATIN SMALL LETTER H
jis208 (20, 22) '\x82\x89' U+FF49 FULLWIDTH LATIN SMALL LETTER I
jis208 (22, 24) '\x82\x86' U+FF46 FULLWIDTH LATIN SMALL LETTER F
jis208 (24, 26) '\x82\x94' U+FF54 FULLWIDTH LATIN SMALL LETTER T
ascii (26, 27) '[' U+005B LEFT SQUARE BRACKET
jis208 (27, 29) '\x82\x8a' U+FF4A FULLWIDTH LATIN SMALL LETTER J
jis208 (29, 31) '\x82\x89' U+FF49 FULLWIDTH LATIN SMALL LETTER I
jis208 (31, 33) '\x82\x93' U+FF53 FULLWIDTH LATIN SMALL LETTER S
ascii (33, 34) '@' U+0040 COMMERCIAL AT
jis208 (34, 36) '\x82\x93' U+FF53 FULLWIDTH LATIN SMALL LETTER S
jis208 (36, 38) '\x82\x94' U+FF54 FULLWIDTH LATIN SMALL LETTER T
jis208 (38, 40) '\x82\x92' U+FF52 FULLWIDTH LATIN SMALL LETTER R
jis208 (40, 42) '\x82\x89' U+FF49 FULLWIDTH LATIN SMALL LETTER I
jis208 (42, 44) '\x82\x8e' U+FF4E FULLWIDTH LATIN SMALL LETTER N
jis208 (44, 46) '\x82\x87' U+FF47 FULLWIDTH LATIN SMALL LETTER G
ascii (46, 47) 'B' U+0042 LATIN CAPITAL LETTER B
Примечание 1: Вам НЕ нужно циклически повторяться и присоединяться к диапазонам символов O (N ** 2).
Если «jascii» означает «ПИСЬМО ПОЛНОЙ ШИРИНЫ (КАПИТАЛ | МАЛЕНЬКИЙ) [AZ]» (a) ваша сеть слишком велика (b) вы можете легко это сделать, используя диапазоны символов UNICODE вместо диапазонов BYTE (после конечно расшифровываю ваши данные).