2010-04-23 16 views
19

estoy tratando de aprender Python y no podía encontrar la manera de traducir el siguiente script Perl a Python:Cómo reemplazar caracteres unicode por caracteres ascii en Python (secuencia de comandos perl dada)?

#!/usr/bin/perl -w      

use open qw(:std :utf8); 

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

El guión sólo cambia diéresis Unicode a ASCII de salida alternativa. (Entonces la salida completa está en ascii.) Agradecería cualquier pista. ¡Gracias!

+0

búsqueda SO para "transliteración" para encontrar preguntas relacionadas. – hop

+0

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

+0

El script de Perl dado en realidad solo sustituirá la primera ocurrencia en cada línea, pero eso seguramente es un accidente. – tripleee

Respuesta

17
  • utilizar el módulo fileinput a un bucle sobre la entrada estándar o una lista de archivos,
  • decodificar las líneas que se leen de UTF-8 a Unicode objetos
  • a continuación, asignar los caracteres Unicode que desea con el método translate

translit.py se vería así:

#!/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), 

Y se podría utilizar de esta manera:

$ 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 
  • Actualización:

Si estás usando Python 3 cadenas son por Unicode defecto y usted 'no tienen que codificar si contiene caracteres que no sean ASCII o incluso caracteres no latinos. Así que la solución se verá de la siguiente manera:

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

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

line.translate(table) 

>>> 'Verhaeltnismaessigkeit, Moeglichkeit' 
+0

Y para obtener la salida de ASCII, la última línea debería ser 'print s.translate (table) .encode ('ascii', 'ignore')', supongo. – Frank

+0

estrictamente hablando, el .pl original no hace eso tampoco, pero sí, esa sería una solución – hop

+5

El objetivo parece ser el deuminio del texto alemán, dejándolo comprensible. El efecto de 'ord (u'ß '): None' en este código es ** eliminar ** el carácter ß (" eszett "). Debería ser 'ord (u'ß '): u'ss''. ¿Upvotes? ¿Respuesta aceptada? –

36

Para convertir a ASCII es posible que desee probar ASCII, Dammit o this recipe, que se reduce 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

que no hace nada lo que hace el .pl original (principalmente transliterando caracteres especiales alemanes) – hop

+3

Sí, pero en realidad hace exactamente lo que necesitaba ¡ahora! –

+3

große -> groe?!? –

3

utilizo 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 

Puede cambiar el idioma de decodificación a lo que necesite. Es posible que desee una función simple para reducir la duración de una sola implementación.

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

Usted podría intentar unidecode para convertir Unicode en ASCII en lugar de escribir expresiones regulares manuales. Es un puerto de Python Text::Unidecode módulo de 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) 

Utiliza FileInput clase para evitar el estado global.

Ejemplo:

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