【问题标题】:how to decode a non unicode character in python?如何在python中解码非Unicode字符?
【发布时间】:2011-04-21 16:03:56
【问题描述】:

我有一个字符串说s = 'Chocolate Moelleux-M\xe8re' 当我在做的时候:

In [14]: unicode(s)
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 20: ordinal not in range(128)

同样,当我尝试使用 s.decode() 对其进行解码时,它返回相同的错误。

In [13]: s.decode()
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 20: ordinal not in range(128)

如何将这样的字符串解码成 unicode。

【问题讨论】:

    标签: python unicode


    【解决方案1】:

    我不得不多次面对这个问题。我在不同编码方案中包含字符串的问题。所以我写了一个方法,根据不同编码的某些特征,启发式地解码一个字符串。

    def decode_heuristically(string, enc = None, denc = sys.getdefaultencoding()):
        """
        Try to interpret 'string' using several possible encodings.
        @input : string, encode type.
        @output: a list [decoded_string, flag_decoded, encoding]
        """
        if isinstance(string, unicode): return string, 0, "utf-8"
        try:
            new_string = unicode(string, "ascii")
            return string, 0, "ascii"
        except UnicodeError:
            encodings = ["utf-8","iso-8859-1","cp1252","iso-8859-15"]
    
            if denc != "ascii": encodings.insert(0, denc)
    
            if enc: encodings.insert(0, enc)
    
            for enc in encodings:
                if (enc in ("iso-8859-15", "iso-8859-1") and
                    re.search(r"[\x80-\x9f]", string) is not None):
                    continue
    
                if (enc in ("iso-8859-1", "cp1252") and
                    re.search(r"[\xa4\xa6\xa8\xb4\xb8\xbc-\xbe]", string)\
                    is not None):
                    continue
    
                try:
                    new_string = unicode(string, enc)
                except UnicodeError:
                    pass
                else:
                    if new_string.encode(enc) == string:
                        return new_string, 0, enc
    
            # If unable to decode,doing force decoding i.e.neglecting those chars.
            output = [(unicode(string, enc, "ignore"), enc) for enc in encodings]
            output = [(len(new_string[0]), new_string) for new_string in output]
            output.sort()
            new_string, enc = output[-1][1]
            return new_string, 1, enc
    

    要添加到此链接,请提供有关编码等原因的良好反馈 - Why we need sys.setdefaultencoging in py script

    【讨论】:

      【解决方案2】:

      您需要告诉 s.decode 您的编码。在您的情况下,s.decode('latin-1') 似乎很合适。

      【讨论】:

      • 它能在所有情况下帮助我吗?有没有通用的解决方案?
      • 我们能否从原始字符串中删除我的示例中的“\x”等字符。
      • @alis:您可以使用 chardet (chardet.feedparser.org) 来猜测编码。
      • s.decode('ascii','ignore') 将取出所有“奇怪”字符
      • @alis:这会将Chocolate Moelleux-Mère 转换为Chocolate Moelleux-Mre。我不明白这怎么可能是任何事情的实际解决方案。此外,假设您遇到Мойст Шоколад Матери 的 ISO-8859-5 编码版本。如果您通过忽略所有非 ascii 字符对其进行解码,则剩下的只是两个空白。换句话说,通过指定匹配的编码来解码你的字符串。在您的示例中,unicode(s, 'latin-1').
      猜你喜欢
      • 2018-09-21
      • 2019-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-01
      • 2020-03-30
      • 1970-01-01
      • 2023-04-06
      相关资源
      最近更新 更多