Ich habe eine Unicode-Zeichenfolge in Python und möchte alle Akzente (diakritische Zeichen) entfernen.
Ich habe im Web eine elegante Möglichkeit gefunden, dies in Java zu tun:
- Konvertieren Sie die Unicode-Zeichenfolge in ihre lange normalisierte Form (mit einem separaten Zeichen für Buchstaben und Diakritika).
- Entfernen Sie alle Zeichen, deren Unicode-Typ "diakritisch" ist.
Muss ich eine Bibliothek wie pyICU installieren oder ist dies nur mit der Python-Standardbibliothek möglich? Und was ist mit Python 3?
Wichtiger Hinweis: Ich möchte Code mit einer expliziten Zuordnung von Zeichen mit Akzent zu ihrem Gegenstück ohne Akzent vermeiden.
python
python-3.x
unicode
python-2.x
diacritics
MiniQuark
quelle
quelle
unidecode
ersetzt°
durchdeg
. Es ist mehr als nur das Entfernen von Akzenten.Wie wäre es damit:
Dies funktioniert auch bei griechischen Buchstaben:
Die Zeichenkategorie "Mn" steht für
Nonspacing_Mark
, ähnlich wie unicodedata.combining in der Antwort von MiniQuark (ich habe nicht an unicodedata.combining gedacht, aber es ist wahrscheinlich die bessere Lösung, weil es expliziter ist).Beachten Sie jedoch, dass diese Manipulationen die Bedeutung des Textes erheblich verändern können. Akzente, Umlaute usw. sind keine "Dekoration".
quelle
unicodedata.name
oder eine ähnliche Tabelle verwenden, die Sie ohnehin für griechische Buchstaben benötigen (Α ist nur "GREEK CAPITAL LETTER ALPHA").A
. Wenn Sie es nicht wollen, tun Sie es nicht, aber in beiden Fällen ersetzen Sie ein lateinisches (fast) ähnliches Aussehen.ß
sichss
im Beispiel nicht in ASCII . Ich würde immer noch verwendenunidecode
, um Unfälle zu vermeiden.Ich habe gerade diese Antwort im Web gefunden:
Es funktioniert gut (zum Beispiel für Französisch), aber ich denke, der zweite Schritt (Entfernen der Akzente) könnte besser gehandhabt werden als das Löschen der Nicht-ASCII-Zeichen, da dies für einige Sprachen (z. B. Griechisch) fehlschlägt. Die beste Lösung wäre wahrscheinlich, die Unicode-Zeichen, die als diakritisch gekennzeichnet sind, explizit zu entfernen.
Bearbeiten : das macht den Trick:
unicodedata.combining(c)
wird true zurückgeben, wenn das Zeichenc
mit dem vorhergehenden Zeichen kombiniert werden kann, dh hauptsächlich, wenn es diakritisch ist.Bearbeiten 2 :
remove_accents
Erwartet eine Unicode- Zeichenfolge, keine Byte-Zeichenfolge. Wenn Sie eine Byte-Zeichenfolge haben, müssen Sie diese in eine Unicode-Zeichenfolge wie folgt dekodieren:quelle
nkfd_form = unicodedata.normalize('NFKD', unicode(input_str, 'utf8'))
, 'utf8'
ist ein "Sicherheitsnetz", das benötigt wird, wenn Sie Eingaben im Terminal testen (das standardmäßig keinen Unicode verwendet). Aber in der Regel Sie nicht haben , um es hinzuzufügen, denn wenn Sie Akzente sind zu entfernen danninput_str
sehr wahrscheinlich ist bereits seine utf8. Es tut jedoch nicht weh, in Sicherheit zu sein.remove_accents
anstelle einer regulären Zeichenfolge übergeben (u "é" anstelle von "é"). Sie haben eine reguläre Zeichenfolge an übergebenremove_accents
. Beim Versuch, Ihre Zeichenfolge in eine Unicode-Zeichenfolge zu konvertieren, wurde die Standardcodierungascii
verwendet. Diese Codierung unterstützt kein Byte mit einem Wert> 127. Wenn Sie "é" in Ihre Shell eingegeben haben, hat Ihr Betriebssystem dies codiert, wahrscheinlich mit UTF-8 oder einer Windows-Codepage-Codierung, und dies beinhaltete Bytes> 127. Ich werde meine Funktion ändern, um die Konvertierung in Unicode zu entfernen: Sie wird deutlicher bombardiert, wenn eine Nicht-Unicode-Zeichenfolge übergeben wird.Eigentlich arbeite ich an projektkompatiblem Python 2.6, 2.7 und 3.4 und muss IDs aus freien Benutzereinträgen erstellen.
Dank dir habe ich diese Funktion geschaffen, die Wunder wirkt.
Ergebnis:
quelle
text = unicode(text, 'utf-8')
. Eine Problemumgehung dafür war hinzuzufügenexcept TypeError: pass
Dies behandelt nicht nur Akzente, sondern auch "Striche" (wie in ø usw.):
Dies ist die eleganteste Art, die ich mir vorstellen kann (und sie wurde von alexis in einem Kommentar auf dieser Seite erwähnt), obwohl ich sie in der Tat nicht für sehr elegant halte. Tatsächlich ist es eher ein Hack, wie in Kommentaren erwähnt, da Unicode-Namen - eigentlich nur Namen - keine Garantie dafür geben, dass sie konsistent sind oder so.
Es gibt immer noch spezielle Buchstaben, die hiervon nicht behandelt werden, z. B. umgedrehte und invertierte Buchstaben, da ihr Unicode-Name kein 'WITH' enthält. Es hängt davon ab, was Sie sowieso tun möchten. Ich brauchte manchmal Akzententfernung, um die Sortierreihenfolge des Wörterbuchs zu erreichen.
NOTIZ BEARBEITEN:
Enthaltene Vorschläge aus den Kommentaren (Behandlung von Suchfehlern, Python-3-Code).
quelle
unicode
Funktionsaufruf mit Python 3? Ich denke, ein engerer regulärer Ausdruck anstelle vonfind
würde alle im obigen Kommentar erwähnten Probleme vermeiden, und Memoisierung würde die Leistung verbessern, wenn es sich um einen kritischen Codepfad handelt.unicode
Typecast ist in Python 3 nicht mehr geeignet. Meiner Erfahrung nach gibt es keine universelle, elegante Lösung für dieses Problem. Je nach Anwendung hat jeder Ansatz seine Vor- und Nachteile. Qualitätsbewusste Werkzeuge wieunidecode
basieren auf handgefertigten Tischen. Einige Ressourcen (Tabellen, Algorithmen) werden von Unicode bereitgestellt, z. zur Zusammenstellung.Als Antwort auf die Antwort von @ MiniQuark:
Ich habe versucht, eine halbfranzösische CSV-Datei (mit Akzenten) und einige Zeichenfolgen einzulesen, die schließlich zu Ganzzahlen und Gleitkommazahlen werden. Als Test habe ich eine
test.txt
Datei erstellt, die folgendermaßen aussieht:Ich musste Zeilen einfügen
2
und3
es zum Laufen bringen (was ich in einem Python-Ticket gefunden habe) sowie @ Jabbas Kommentar einfügen:Das Ergebnis:
(Hinweis: Ich arbeite unter Mac OS X 10.8.4 und verwende Python 2.7.3.)
quelle
remove_accents
sollte Akzente aus einer Unicode-Zeichenfolge entfernen. Falls eine Byte-Zeichenfolge übergeben wird, wird versucht, diese mit in eine Unicode-Zeichenfolge zu konvertierenunicode(input_str)
. Dies verwendet die Standardcodierung von Python, "ascii". Da Ihre Datei mit UTF-8 codiert ist, schlägt dies fehl. In den Zeilen 2 und 3 wird die Standardcodierung von Python in UTF-8 geändert. Dann funktioniert es, wie Sie herausgefunden haben. Eine andere Möglichkeit besteht darin,remove_accents
eine Unicode-Zeichenfolge zu übergeben: Entfernen Sie die Zeilen 2 und 3 und ersetzen Sie sie in der letzten Zeileelement
durchelement.decode("utf-8")
. Ich habe getestet: es funktioniert. Ich werde meine Antwort aktualisieren, um dies klarer zu machen.iso-8859-1
reload(sys); sys.setdefaultencoding("utf-8")
ist ein zweifelhafter Hack, der manchmal für Windows-Systeme empfohlen wird. Weitere Informationen finden Sie unter stackoverflow.com/questions/28657010/… .gensim.utils.deaccent (Text) von Gensim - Themenmodellierung für Menschen :
Eine andere Lösung ist Unidecode .
Beachten Sie, dass die vorgeschlagene Lösung mit Unicodedata normalerweise nur in bestimmten Zeichen Akzente entfernt (z. B.
'ł'
in''
und nicht in'l'
).quelle
deaccent
gibt immer nochł
stattl
.NumPy
undSciPy
Akzente entfernen lassen.In einigen Sprachen werden Diakritika als Sprachbuchstaben und Akzentdiakritika kombiniert, um den Akzent festzulegen.
Ich denke, es ist sicherer, explizit anzugeben, welche Diakrika Sie entfernen möchten:
quelle