2009-05-30 16 views
5

que tengo una base de datos completa de los nombres como:Python Cuerda de limpieza + Manipulación (caracteres acentuados)

John Smith 
Scott J. Holmes 
Dr. Kaplan 
Ray's Dog 
Levi's 
Adrian O'Brien 
Perry Sean Smyre 
Carie Burchfield-Thompson 
Björn Árnason 

Hay algunos nombres extranjeros con acentos en los que necesitan ser convertidos a cadenas con caracteres no acentuados .

me gustaría convertir los nombres completos (después de quitar caracteres como "'", "-") a inicios de sesión de usuario como:

john.smith 
scott.j.holmes 
dr.kaplan 
rays.dog 
levis 
adrian.obrien 
perry.sean.smyre 
carie.burchfieldthompson 
bjorn.arnason 

Hasta ahora tengo:

Fullname.strip() # get rid of leading/trailing white space 
Fullname.lower() # make everything lower case 


... # after bad chars converted/removed 
Fullname.replace(' ', '.') # replace spaces with periods 
+1

** Malo e incorrecto **, y sumariamente ofensivo, mutilar a todos esos personajes. Ni siquiera puedes escribir en inglés correctamente si haces esto. ¡ASCII está muerto! – tchrist

Respuesta

12

echar un vistazo a este enlace [redactado]

Aquí está el código de la página

def latin1_to_ascii (unicrap): 
    """This replaces UNICODE Latin-1 characters with 
    something equivalent in 7-bit ASCII. All characters in the standard 
    7-bit ASCII range are preserved. In the 8th bit range all the Latin-1 
    accented letters are stripped of their accents. Most symbol characters 
    are converted to something meaningful. Anything not converted is deleted. 
    """ 
    xlate = { 
     0xc0:'A', 0xc1:'A', 0xc2:'A', 0xc3:'A', 0xc4:'A', 0xc5:'A', 
     0xc6:'Ae', 0xc7:'C', 
     0xc8:'E', 0xc9:'E', 0xca:'E', 0xcb:'E', 
     0xcc:'I', 0xcd:'I', 0xce:'I', 0xcf:'I', 
     0xd0:'Th', 0xd1:'N', 
     0xd2:'O', 0xd3:'O', 0xd4:'O', 0xd5:'O', 0xd6:'O', 0xd8:'O', 
     0xd9:'U', 0xda:'U', 0xdb:'U', 0xdc:'U', 
     0xdd:'Y', 0xde:'th', 0xdf:'ss', 
     0xe0:'a', 0xe1:'a', 0xe2:'a', 0xe3:'a', 0xe4:'a', 0xe5:'a', 
     0xe6:'ae', 0xe7:'c', 
     0xe8:'e', 0xe9:'e', 0xea:'e', 0xeb:'e', 
     0xec:'i', 0xed:'i', 0xee:'i', 0xef:'i', 
     0xf0:'th', 0xf1:'n', 
     0xf2:'o', 0xf3:'o', 0xf4:'o', 0xf5:'o', 0xf6:'o', 0xf8:'o', 
     0xf9:'u', 0xfa:'u', 0xfb:'u', 0xfc:'u', 
     0xfd:'y', 0xfe:'th', 0xff:'y', 
     0xa1:'!', 0xa2:'{cent}', 0xa3:'{pound}', 0xa4:'{currency}', 
     0xa5:'{yen}', 0xa6:'|', 0xa7:'{section}', 0xa8:'{umlaut}', 
     0xa9:'{C}', 0xaa:'{^a}', 0xab:'<<', 0xac:'{not}', 
     0xad:'-', 0xae:'{R}', 0xaf:'_', 0xb0:'{degrees}', 
     0xb1:'{+/-}', 0xb2:'{^2}', 0xb3:'{^3}', 0xb4:"'", 
     0xb5:'{micro}', 0xb6:'{paragraph}', 0xb7:'*', 0xb8:'{cedilla}', 
     0xb9:'{^1}', 0xba:'{^o}', 0xbb:'>>', 
     0xbc:'{1/4}', 0xbd:'{1/2}', 0xbe:'{3/4}', 0xbf:'?', 
     0xd7:'*', 0xf7:'/' 
    } 

    r = '' 
    for i in unicrap: 
     if xlate.has_key(ord(i)): 
      r += xlate[ord(i)] 
     elif ord(i) >= 0x80: 
      pass 
     else: 
      r += i 
    return r 

# This gives an example of how to use latin1_to_ascii(). 
# This creates a string will all the characters in the latin-1 character set 
# then it converts the string to plain 7-bit ASCII. 
if __name__ == '__main__': 
s = unicode('','latin-1') 
for c in range(32,256): 
    if c != 0x7f: 
     s = s + unicode(chr(c),'latin-1') 
print 'INPUT:' 
print s.encode('latin-1') 
print 
print 'OUTPUT:' 
print latin1_to_ascii(s) 
+0

Tu enlace me lleva a "Britney Spears desnuda" – mpen

+2

@Mark - ¡Ja, hurra por la permanencia de los enlaces web! –

1

me gustaría hacer algo como esto

# coding=utf-8 

def alnum_dot(name, replace={}): 
    import re 

    for k, v in replace.items(): 
     name = name.replace(k, v) 

    return re.sub("[^a-z.]", "", name.strip().lower()) 

print alnum_dot(u"Frédrik Holmström", { 
    u"ö":"o", 
    " ":"." 
}) 

segundo argumento es un diccionario de los caracteres que desea sustituidas, no todas a-z y. los caracteres que no se reemplacen se quitarán

1

El método de traducción le permite eliminar caracteres. Puede usar eso para eliminar caracteres arbitrarios.

Fullname.translate(None,"'-\"") 

Si desea eliminar clases enteras de caracteres, es posible que desee utilizar el módulo re.

re.sub('[^a-z0-9 ]', '', Fullname.strip().lower(),) 
3

La siguiente función es genérico:

import unicodedata 

def not_combining(char): 
     return unicodedata.category(char) != 'Mn' 

def strip_accents(text, encoding): 
     unicode_text= unicodedata.normalize('NFD', text.decode(encoding)) 
     return filter(not_combining, unicode_text).encode(encoding) 

# in a cp1252 environment 
>>> print strip_accents("déjà", "cp1252") 
deja 
# in a cp1253 environment 
>>> print strip_accents("καλημέρα", "cp1253") 
καλημερα 

Obviamente, usted debe conocer la codificación de sus cadenas.

5

Si no tiene miedo de instalar módulos de terceros, eche un vistazo al python port of the Perl module Text::Unidecode (también es on pypi).

El módulo no hace más que usar una tabla de búsqueda para transcribir los caracteres. Eché un vistazo al código y parece muy simple. Así que supongo que está funcionando en casi cualquier sistema operativo y en cualquier versión de Python (crossingfingers). También es fácil de combinar con su aplicación.

Con este módulo no tiene que crear su tabla de búsqueda manualmente (= reduce el riesgo de que esté incompleta).

La ventaja de este módulo en comparación con la técnica de normalización Unicode es la siguiente: la normalización Unicode no reemplaza todos los caracteres. Un buen ejemplo es un personaje como "æ". La normalización Unicode lo verá como "Letra, minúscula" (Ll). Esto significa que usar el método normalize no le dará ni un carácter de reemplazo ni una pista útil. Desafortunadamente, ese personaje no es representable en ASCII. Entonces obtendrás errores

El mencionado module hace un mejor trabajo en esto. Esto realmente reemplazará el "æ" con "ae". Lo cual es realmente útil y tiene sentido.

Lo más impresionante que he visto es que va mucho más allá.Incluso reemplaza los caracteres Kana japoneses principalmente correctamente. Por ejemplo, reemplaza "は" por "ha". Lo cual está perfectamente bien. No es a prueba de tontos, ya que la versión actual reemplaza "ち" por "ti" en lugar de "chi". Por lo tanto, tendrá que manejarlo con cuidado para los personajes más exóticos.

Uso del módulo es sencillo ::

from unidecode import unidecode 
var_utf8 = "æは".decode("utf8") 
unidecode(var_utf8).encode("ascii") 
>>> "aeha" 

Tenga en cuenta que no tengo nada que ver con este módulo directamente. Simplemente sucede que lo encuentro muy útil.

Editar: El parche que envié corrigió el error relacionado con el kana japonés. Solo he arreglado el que pude detectar de inmediato. Puede que me haya perdido algo.

+0

Ayer envié un parche para solucionar los problemas con los reemplazos de kana mencionados. ¡Ya se ha fusionado! – exhuma

Cuestiones relacionadas