3

目前我有一个用 python 编写的简单 IRC 机器人。

自从我将它迁移到区分字节和 unicode 字符串的 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

在消息很短的情况下(IRC 就是这种情况),仅使用 chardet 会导致较差的结果。

Chardet 结合在整个消息中记住特定用户的编码可能是有意义的。但是,为简单起见,我会使用一些可能的编码(编码取决于文化和时代,请参阅http://en.wikipedia.org/wiki/Internet_Relay_Chat#Character_encoding),如果它们失败了,我会去 chardet(如果有人使用一些东亚编码,这将帮助我们)。

例如:

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

好的,经过一些研究发现 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 回答