非ASCII文字/バイトに問題がある場合、それらをコンソールに印刷して、質問にコピー/貼り付けするのはかなり役に立ちません。あなたが見るものは、あなたが持っているものではないことがよくあります。組み込みrepr()
関数[ ascii()
Python3.x:]を使用して、データをできるだけ明確に表示する必要があります。
これを行う:
python -c "print repr(open('shiftjis.txt', 'rb').read())"
結果をコピーして貼り付け、質問を編集します。
悟りを待っている間にデータをリバースエンジニアリングする:Windowsコードページはcp1252
、最も一般的なものとして、疑わしいものである必要があります。@Mark Tolonenが示したように、cp1252
1つのエラーで、ほぼ適合します。さらに調査すると、他のcp125x
エンコーディングでは2、3、または5つのエラーが発生することがわかります。AFAIKは、cp125x
エンコーディングのみがコンマ(実際にはU + 201A SINGLE LOW-9 QUOTATION MARK)のように見えるものをshift-jisリードバイトにマップします\x82
。cp1252
違反者はであり、エラーは輸送中の損傷が原因であると結論付けます。
もう1つの可能性は、基礎となる元のエンコーディングが、日本のWindowsで使用されているshift-jis
Microsoftのスーパーセットではないことです。cp932
ただし、問題のあるシーケンス'\x82@'
はどちらでも有効ではありませんcp932
。いずれにせよ、処理したいファイルが日本のWindowsマシンからのものである場合は、よりも使用する方がよいでしょcp932
うshift-jis
。
質問とコードから、データをUnicodeにデコードするのではなく、何をしたいのか、なぜバイト範囲でそれを実行したいのかは明らかではありません。私は使用しませんpyparsing
が、あなたがそれを供給しているサブレンジが奇形である可能性が高いようです。
以下は、正規表現を使用して入力をトークン化する方法の例です。pyparsingの構文が少し異なることに注意してください(\0xff
Pythonの `\ xff'の代わりに)。
コード:
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」が単に「FULLWIDTHLATIN(CAPITAL | SMALL)LETTER [AZ]」を意味する場合、(a)ネットが大きすぎる(b)BYTE範囲の代わりにUNICODE文字範囲を使用して簡単に行うことができます(もちろん、データ)。