2010-04-23 9 views
19

Sto cercando di imparare Python e non riusciva a capire come tradurre il seguente script perl per python:Come sostituire i caratteri unicode con caratteri ascii in Python (dato lo script perl)?

#!/usr/bin/perl -w      

use open qw(:std :utf8); 

while(<>) { 
    s/\x{00E4}/ae/; 
    s/\x{00F6}/oe/; 
    s/\x{00FC}/ue/; 
    print; 
} 

Lo script cambia solo dieresi Unicode in uscita ascii alternativa. (Quindi l'output completo è in ascii.) Sarei grato per qualsiasi suggerimento. Grazie!

+0

di ricerca in modo per "traslitterazione" per trovare questioni connesse. – hop

+0

http://stackoverflow.com/questions/816285/where-is-pythons-best-ascii-for-this-unicode-database/816319#816319 – hop

+0

Il dato script Perl in realtà sostituirà solo la prima occorrenza su ciascuna riga, ma questo è sicuramente un incidente. – tripleee

risposta

17
  • utilizzare il modulo fileinput al ciclo su standard input o un elenco di file,
  • decodificare le righe si legge da UTF-8 a Unicode oggetti
  • poi mappare qualsiasi caratteri unicode che volete con il metodo translate

translit.py sarebbe simile a questa:

#!/usr/bin/env python2.6 
# -*- coding: utf-8 -*- 

import fileinput 

table = { 
      0xe4: u'ae', 
      ord(u'ö'): u'oe', 
      ord(u'ü'): u'ue', 
      ord(u'ß'): None, 
     } 

for line in fileinput.input(): 
    s = line.decode('utf8') 
    print s.translate(table), 

E si potrebbe usare in questo modo:

$ cat utf8.txt 
sömé täßt 
sömé täßt 
sömé täßt 

$ ./translit.py utf8.txt 
soemé taet 
soemé taet 
soemé taet 
  • Aggiornamento:

Nel caso in cui si sta utilizzando Python 3 stringhe sono di Unicode impostazione predefinita e si Dont' bisogno di codificarlo se contiene caratteri non ASCII o anche caratteri non latini. Quindi la soluzione sarà come segue:

line = 'Verhältnismäßigkeit, Möglichkeit' 

table = { 
     ord('ä'): 'ae', 
     ord('ö'): 'oe', 
     ord('ü'): 'ue', 
     ord('ß'): 'ss', 
     } 

line.translate(table) 

>>> 'Verhaeltnismaessigkeit, Moeglichkeit' 
+0

E per ottenere l'output ASCII l'ultima riga dovrebbe essere 'print s.translate (table) .encode ('ascii', 'ignore')', immagino. – Frank

+0

in senso stretto l'originale .pl non lo fa, ma sì, quella sarebbe una soluzione – hop

+5

L'obiettivo sembra essere de-umlauting del testo tedesco, lasciandolo comprensibile. L'effetto di 'ord (u'ß '): None' in questo codice è quello di ** cancellare ** il carattere ß (" eszett "). Dovrebbe essere 'ord (u'ß'): u'ss''. Upvotes ?? Risposta accettata ??? –

36

Per la conversione in ASCII si potrebbe desiderare di provare ASCII, Dammit o this recipe, che si riduce a:

>>> title = u"Klüft skräms inför på fédéral électoral große" 
>>> import unicodedata 
>>> unicodedata.normalize('NFKD', title).encode('ascii','ignore') 
'Kluft skrams infor pa federal electoral groe' 
+2

che non ha affatto quello che fa il file .pl originale (principalmente traslitterando correttamente caratteri speciali tedeschi) – hop

+3

Sì, ma in realtà fa esattamente quello di cui avevo bisogno giusto adesso! –

+3

große -> groe?!? –

3

Io uso translitcodec

>>> import translitcodec 
>>> print '\xe4'.decode('latin-1') 
ä 
>>> print '\xe4'.decode('latin-1').encode('translit/long').encode('ascii') 
ae 
>>> print '\xe4'.decode('latin-1').encode('translit/short').encode('ascii') 
a 

È possibile modificare la lingua di decodifica in base alle proprie esigenze. Potresti voler una funzione semplice per ridurre la lunghezza di una singola implementazione.

def fancy2ascii(s): 
    return s.decode('latin-1').encode('translit/long').encode('ascii') 
3

Si potrebbe provare unidecode per convertire Unicode in ASCII invece di scrivere espressioni regolari manuali. Si tratta di un porto Python di Text::Unidecode modulo Perl:

#!/usr/bin/env python 
import fileinput 
import locale 
from contextlib import closing 
from unidecode import unidecode # $ pip install unidecode 

def toascii(files=None, encoding=None, bufsize=-1): 
    if encoding is None: 
     encoding = locale.getpreferredencoding(False) 
    with closing(fileinput.FileInput(files=files, bufsize=bufsize)) as file: 
     for line in file: 
      print unidecode(line.decode(encoding)), 

if __name__ == "__main__": 
    import sys 
    toascii(encoding=sys.argv.pop(1) if len(sys.argv) > 1 else None) 

Esso utilizza FileInput classe per evitare stato globale.

Esempio:

$ echo 'äöüß' | python toascii.py utf-8 
aouss 
Problemi correlati