0

文字列からバイト順マークを削除する必要があります。BOMを見つけるためのコードはすでにありますが、実際の文字列から削除する必要があります。

例を挙げましょう。BOMfeffの長さは2バイトです。これは、文字列の最初の2バイトが最後の文字列に含まれないことを意味します。ただし、Pythonの文字列ストリッピングを使用すると、文字列から多くのストリッピングが削除されます。

コードスニペット:

print len(bom)
print as_hex(bom)
print string
print as_hex(string)
string = string[len(bom):]
print string
print as_hex(string)

出力:

2
feff
Organ
feff4f7267616e
rgan
7267616e

私が手に入れたいのは:

2
feff
Organ
feff4f7267616e
Organ
4f7267616e

このas_hex()関数は、文字を16進数("".join('%02x' % ord(c) for c in bytes)として出力するだけです。

4

2 に答える 2

4

あなたはUnicode文字列オブジェクトを持っていると思います。(Python 3を使用している場合は、それが唯一の種類の文字列であるため、確かに使用します。)as_hex関数は、最初の文字に「fe」、2番目の文字に「ff」を出力しません。文字列の最初のUnicode文字の「feff」を出力します。例(Python 3):

>>> mystr = "\ufeffHello world."
>>> mystr[0]
'\ufeff'
>>> '%02x' % ord(mystr[0])
'feff'

Unicode文字を1つだけ削除するか、bytes代わりに文字列をオブジェクトに格納して2バイトを削除する必要があります。

(これは、len(bom)が2である理由を説明していません。また、コードを詳しく表示しないとわかりません。bomは、ユニコード文字列ではなく、listまたはbytesオブジェクトであると思います。)


bom上記の私の答えはPython3を想定していますが、印刷ステートメントからPython 2を使用していることがわかりました。それに基づいて、これはASCII文字列でstringあり、はユニコード文字列であると思います。print repr(x)代わりに使用するprint xと、Unicode文字列とASCII文字列の違いがわかります。

于 2012-12-22T23:15:00.663 に答える
0

適切なコーデックを使用すると、BOMが自動的に処理されます。を使用してデコードするutf-8-sigutf16、先頭のBOMが存在する場合は削除されます。それらを使用してエンコードすると、BOMが追加されます。BOMが必要ない場合は、、またはを使用utf-8utf-16leますutf-16be

通常、テキストデータをプログラムに読み込むときはUnicodeにデコードし、ファイル、コンソール、ソケットなどに書き込むときはバイトにエンコードする必要があります。

unicode_str = u'test'
utf8_w_bom = unicode_str.encode('utf-8-sig')
utf16_w_bom = unicode_str.encode('utf16')
utf8_wo_bom = unicode_str.encode('utf-8')
utf16_wo_bom = unicode_str.encode('utf-16le')
print repr(utf8_w_bom)
print repr(utf16_w_bom)
print repr(utf8_wo_bom)
print repr(utf16_wo_bom)
print repr(utf8_w_bom.decode('utf-8-sig'))
print repr(utf16_w_bom.decode('utf16'))
print repr(utf8_wo_bom.decode('utf-8-sig'))
print repr(utf16_wo_bom.decode('utf16'))

出力:

'\xef\xbb\xbftest'
'\xff\xfet\x00e\x00s\x00t\x00'
'test'
't\x00e\x00s\x00t\x00'
u'test'
u'test'
u'test'
u'test'

utf16BOMがない場合、デコード時にネイティブのバイト順序が想定されることに注意してください。

于 2012-12-23T00:26:58.077 に答える