3

現在、Python で書かれた単純な IRC ボットがあります。

バイトとユニコード文字列を区別するpython 3.0に移行してから、エンコードの問題が発生し始めました。具体的には、他のユーザーが UTF-8 を送信していません。

今、私は全員に UTF-8 を送信するように指示することができます (関係なく送信する必要があります) が、さらに良い解決策は、python を他のエンコーディングなどにデフォルト設定することです。

これまでのところ、コードは次のようになります。

data = str(irc.recv(4096),"UTF-8", "replace")

少なくとも例外をスローしません。しかし、私はそれを乗り越えたいと思っています.ボットをデフォルトで別のエンコーディングにするか、何らかの方法で「厄介な文字」を検出しようとしています.

さらに、mIRC が実際に使用しているこの不思議なエンコーディングが何であるかを理解する必要があります。他のクライアントは正常に動作し、本来のように UTF-8 を送信しているように見えます。

それらのことを行うにはどうすればよいですか?

4

4 に答える 4

3

chardetが役立つはずです。不明なエンコーディングを検出するための正規の Python ライブラリです。

于 2009-06-02T10:45:28.817 に答える
0

RichieHindle が述べたように、chardet はおそらく最良の解決策になるでしょう。ただし、テキストの約 90% をカバーしたい場合は、私が使用するものを使用できることがわかります。

def decode(bytes):
    try:
        text = bytes.decode('utf-8')
    except UnicodeDecodeError:
        try:
            text = bytes.decode('iso-8859-1')
        except UnicodeDecodeError:
            text = bytes.decode('cp1252')
    return text


def encode(bytes):
    try:
        text = bytes.encode('utf-8')
    except UnicodeEncodeError:
        try:
            text = bytes.encode('iso-8859-1')
        except UnicodeEncodeError:
            text = bytes.encode('cp1252')
    return text
于 2012-04-21T00:29:07.587 に答える
0

chardet のみを使用すると、メッセージが短い状況 (IRC の場合) では不十分な結果になります。

メッセージ全体で特定のユーザーのエンコーディングを記憶することと組み合わせたシャルデは理にかなっています。ただし、簡単にするために、いくつかの推定可能なエンコーディングを使用します (エンコーディングは文化と時代に依存します。http://en.wikipedia.org/wiki/Internet_Relay_Chat#Character_encodingを参照) 。東アジアのエンコーディングの一部を使用しているため、これが役立ちます)。

例えば:

def decode_irc(raw, preferred_encs = ["UTF-8", "CP1252", "ISO-8859-1"]):
    changed = False
    for enc in preferred_encs:
        try:
            res = raw.decode(enc)
            changed = True
            break
        except:
            pass
    if not changed:
        try:
            enc = chardet.detect(raw)['encoding']
            res = raw.decode(enc)
        except:
            res = raw.decode(enc, 'ignore')
return res
于 2012-07-11T15:03:06.113 に答える
-1

OK、いくつかの調査の結果、chardet が python 3 で問題を抱えていることが判明しました。結局のところ、解決策は思ったよりも簡単です。UTF-8 でカットできない場合は、CP1252 にフォールバックすることにしました。

data = irc.recv ( 4096 )
try: data = str(data,"UTF-8")
except UnicodeDecodeError: data = str(data,"CP1252")

これは機能しているようです。ただし、エンコーディングは検出されないため、誰かが UTF-8 でも CP1252 でもないエンコーディングを使用した場合、再び問題が発生します。

これは本当に一時的な解決策です。

于 2009-06-02T11:59:04.597 に答える