2010-10-06 11 views
5

ich eine Zeichenfolge haben sagen s = 'Chocolate Moelleux-M\xe8re' Wenn ich tue:Wie dekodiert man ein Nicht-Unicode-Zeichen in Python?

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) 

Ähnlich, wenn ich versuche, diese zu entschlüsseln, indem s.decode() mit ihm gleichen Fehler zurückgibt.

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) 

So dekodieren Sie solche Zeichenfolge in Unicode.

Antwort

10

Ich musste dieses Problem zu oft stellen. Das Problem, dass ich Strings in verschiedenen Kodierungsschemata enthalten hatte. Also habe ich eine Methode geschrieben, um einen String heuristisch zu dekodieren, basierend auf bestimmten Merkmalen verschiedener Kodierungen.

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 

Um diese Erweiterung Link auf, warum Codierung usw. ein gutes Feedback gibt - Why we need sys.setdefaultencoging in py script

4

Sie müssen s.code Ihre Codierung mitteilen. In Ihrem Fall scheint s.decode('latin-1') passend.

+0

es wird mir in alle Situation helfen? Gibt es eine generalisierte Lösung? – user12345

+0

Können wir diese Zeichen wie '\ x' in meinem Beispiel von der ursprünglichen Zeichenfolge entfernen. – user12345

+0

@alis: Sie könnten chardet (http://chardet.feedparser.org/) verwenden, um die Codierung zu erraten. – johnbaum

Verwandte Themen