2010-10-06 14 views
5

Ho una stringa dicono s = 'Chocolate Moelleux-M\xe8re' quando sto facendo:come decodificare un carattere non unicode 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) 

Allo stesso modo in cui sto provando a decodificare questo utilizzando s.decode() restituisce lo stesso errore.

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) 

Come decodificare tale stringa in unicode.

risposta

10

Ho dovuto affrontare questo problema troppe volte. Il problema che avevo contenuto stringhe in diversi schemi di codifica. Così ho scritto un metodo per decodificare una stringa euristicamente basata su alcune caratteristiche di diverse codifiche.

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 

Per aggiungere a questo link dà un buon feedback sul motivo per cui la codifica ecc - Why we need sys.setdefaultencoging in py script

4

È necessario dire s.decode la codifica. Nel tuo caso s.decode('latin-1') sembra appropriato.

+0

sta andando per aiutare me in tutta la situazione? C'è una soluzione generalizzata? – user12345

+0

Possiamo rimuovere quei caratteri come '\ x' nel mio esempio, dalla stringa originale. – user12345

+0

@alis: è possibile utilizzare chardet (http://chardet.feedparser.org/) per indovinare la codifica. – johnbaum

Problemi correlati