2009-05-30 2 views
5

ich wie voll Namen eine Datenbank habe:Python String Cleanup + Manipulation (Umlaute)

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

Es gibt ein paar ausländischen Namen mit Akzenten in ihnen, den Saiten mit nicht-akzentuierte Zeichen umgewandelt werden müssen, .

Ich möchte die vollständigen Namen konvertieren (nach Zeichen wie "'", Stripping "-") zu Benutzeranmeldungen wie:

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

Bisher habe ich:

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

Es ist böse und falsch ** und summarisch beleidigend, alle diese Charaktere zu verstümmeln. Sie können nicht einmal Englisch richtig schreiben, wenn Sie dies tun. ASCII ist tot !!! – tchrist

Antwort

12

Werfen Sie einen Blick auf diesen Link [geschwärzt]

Hier ist der Code von der Seite

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

Ihr Link führt mich zu "Britney Spears nackt" – mpen

+2

@Mark - Ha, hurra für die Dauerhaftigkeit von Weblinks! –

1

Ich würde

# 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", 
    " ":"." 
}) 

Zweites Argument so etwas wie dies tun, ist ein dict der Zeichen, die Sie ersetzen möchten, die alle nicht a-z und. Zeichen, die nicht ersetzt werden, werden entfernt

1

Die Translate-Methode ermöglicht das Löschen von Zeichen. Sie können damit beliebige Zeichen löschen.

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

Wenn Sie ganze Klassen von Zeichen löschen möchten, können Sie das re-Modul verwenden.

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

Die folgende Funktion ist generic:

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") 
καλημερα 

Natürlich sollten Sie die Codierung Ihrer Strings kennen.

5

Wenn Sie keine Angst haben, Module von Drittanbietern zu installieren, dann werfen Sie einen Blick auf die python port of the Perl module Text::Unidecode (es ist auch on pypi).

Das Modul verwendet nur eine Nachschlagetabelle, um die Zeichen zu transkribieren. Ich schaute auf den Code und es sieht sehr einfach aus. Ich nehme an, dass es auf so ziemlich jedem Betriebssystem und auf jeder Python-Version (Crossingfingers) funktioniert. Es ist auch einfach, mit Ihrer Anwendung zu bündeln.

Mit diesem Modul müssen Sie Ihre Nachschlagetabelle nicht manuell erstellen (= verringertes Risiko, dass sie unvollständig ist).

Der Vorteil dieses Moduls im Vergleich zur Unicode-Normalisierungstechnik ist folgender: Die Unicode-Normalisierung ersetzt nicht alle Zeichen. Ein gutes Beispiel ist ein Charakter wie "æ". Unicode Normalisierung wird es als "Letter, Kleinbuchstaben" (Ll) sehen. Dies bedeutet, dass die Verwendung der normalize-Methode Ihnen weder ein Ersatzzeichen noch einen nützlichen Hinweis geben wird. Leider ist dieses Zeichen in ASCII nicht darstellbar. Sie werden also Fehler bekommen.

Die erwähnte module macht einen besseren Job bei diesem. Dies wird das "æ" durch "ae" ersetzen. Was eigentlich sinnvoll ist und Sinn macht.

Das Beeindruckendste, was ich gesehen habe, ist, dass es viel weiter geht.Es ersetzt sogar japanische Kana-Zeichen meistens richtig. Zum Beispiel ersetzt es "は" durch "ha". Wich ist vollkommen in Ordnung. Es ist jedoch nicht narrensicher, da die aktuelle Version "ち" durch "ti" anstelle von "chi" ersetzt. Sie müssen also vorsichtig mit den exotischeren Charakteren umgehen.

Verwendung des Moduls ist einfach ::

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

Bitte beachte, dass es nichts direkt mit diesem Modul zu tun. Es kommt einfach vor, dass ich es sehr nützlich finde.

Edit: Der Patch, den ich eingereicht habe, behob den Fehler bezüglich der japanischen Kana. Ich habe nur das repariert, was ich sofort erkennen konnte. Ich habe vielleicht etwas verpasst.

+0

Ich habe gestern einen Patch eingereicht, um die Probleme mit den erwähnten Kana-Ersatz zu beheben. Es wurde bereits zusammengeführt! – exhuma