2009-09-19 7 views
6

私は、その行がUTF-8で2回エンコードされた巨大なMySQLテーブルを持っています。 たとえば、 "Újratárgyalja"は "šjratárgyalja"として格納されます。UTF-8でエンコードされた文字列を単純なUTF-8に2回デコードする方法は?

MySQL .Netコネクタは、このようにダウンロードします。私はSystem.Text.Encoding.Convert()とたくさんの組み合わせを試しましたが、どれも働いていませんでした。

送信set names 'utf8'(または他の文字セット)は解決しません。

ダブルUTF-8からUTF-8にデコードするにはどうすればよいですか?

+1

私はこの質問をupvoteする必要があります。これは主にアレックスの答えを促したからです。これはかなり面白いです。また、エンコーディングは、私自身のマシンでAlexの答えを実験するだけで再発見したので、一般的に扱いにくいビジネスになる可能性があります。彼のアプローチが他の相互運用性の文脈でも(少なくとも手がかりとして)役立つかもしれないという気持ちがある。 –

答えて

8

特有の問題ですが、UTF-8とLatin-1を適切に組み合わせることで再現できると思いますが(UTF-8を2回使用するだけでなく、 。ここでは全体の奇妙な往復(* Pythonの2またはIronPythonのは、この両方を再現することができるはずです)「があると再び」、です:

# -*- coding: utf-8 -*- 
uni = u'Újratárgyalja' 
enc1 = uni.encode('utf-8') 
enc2 = enc1.decode('latin-1').encode('utf-8') 
dec3 = enc2.decode('utf-8') 
dec4 = dec3.encode('latin-1').decode('utf-8') 

for x in (uni, enc1, enc2, dec3, dec4): 
    print repr(x), x 

これは面白い出力されます...:

u'\xdajrat\xe1rgyalja' Újratárgyalja 
'\xc3\x9ajrat\xc3\xa1rgyalja' Újratárgyalja 
'\xc3\x83\xc2\x9ajrat\xc3\x83\xc2\xa1rgyalja' Ãjratárgyalja 
u'\xc3\x9ajrat\xc3\xa1rgyalja' Ãjratárgyalja 
u'\xdajrat\xe1rgyalja' Újratárgyalja 

Ãで始まる変わった文字列は、enc2として表示されます。つまり、ミックスに投じられた散在したlatin-1のデコードを伴う2つのutf-8エンコーディングです。そして、あなたが見ることができるように、正確に逆の操作のシーケンスによって取り消すことができます:utf-8としてデコードし、latin-1として再エンコードし、utf-8として再度デコードして、元の文字列を返します!)。

Latin-1(別名ISO-8859-1)とUTF-8の通常のラウンドトリッププロパティは、このシーケンスが動作することを保証する必要があります(申し訳ありません。しかし、私は、エンコーディング/デコードシーケンスは、使用されている特定のプログラミング言語に依存すべきではないと期待しています)。

+0

独創的。そして答えは受け入れられる。私自身の好奇心のために、Python 2.6.1でWindows上で結果を再現しようとしました。コードのコピーや貼り付けの問題(たとえば、メモ帳やIDLEエディタに貼り付けるなど)が非常に異なっていたため、厳しい状況でした。それから、より多くの問題が発生しました(IDLEの外側にある場合はrepr(x)のみを印刷することに頼らざるを得ませんでした)。 [私は知っている、私は知っている、実際のオペレーティングシステムなどを取得する] –

-1

あなたはMySQLのクエリ・レベルで

SELECT CONVERT(`your_column` USING ascii) 
FROM `your_table` 

を使用して試みることができます。しかし、これは暗闇の中で刺すことです。

1

「MySQL .Netコネクタは、この方法でダウンロードします。これは、MySQLの.NetコネクタがLatin-1からMySQLへ、そしてMySQLが会話がUTF-8であると信じていることを意味します。また、列がLatin-1として宣言される可能性もありますが、実際にはUTF-8データが含まれています。

後者の場合(Latin-1というラベルの列ですが、データは実際にはUTF-8です)、MySQLのテキスト処理関数、列のORDER BYなどを使用すると、不思議な照合の問題やその他のバグが発生します。ここで、テキストは単にワイヤを介して送信されるバイトではなく、「何かを意味する」。

どちらの場合でも、それ以外の場合はシステムを維持しなければならない人にとっては頭痛になるため、根本的な問題を解決するようにしてください。

+0

列はUTF-8として宣言され、そこに格納されたデータもUTF-8ですが、いくつかの不思議な理由でPHPのPDO拡張が2回 – RoliSoft

+0

あなたはこれまでにPHPについて何も言及したことがありません。 MySQL DBではデータが実際に破損していますか? – tialaramex

+0

私は最初の文章でそれを言いました、それはそのようにMySQLデータベースに格納されています。しかし、元の質問はUTF-8で2回エンコードされたC#の文字列をデコードする方法だったので、PHPのPDO拡張がこのように格納されているとは言いませんでした。 – RoliSoft

関連する問題