2013-06-13 15 views
7

Was ist der einfachste Weg, die Zeichenmodifikatoren von einer Unicode-Zeichenfolge in Python zu entfernen?Unicode-Zeichen-Modifizierer entfernen

Zum Beispiel:

arthur Arthur

werden soll ich versucht, die Dokumentation, aber ich konnte nichts finden, dass dies der Fall ist.

Antwort

6

Versuchen Sie, diese

import unicodedata 
a = u"STRING GOES HERE" # using an actual string would break stackoverflow's code formatting. 
u"".join(x for x in a if not unicodedata.category(x).startswith("M")) 

Diese alle Zeichen entfernen wird als Zeichen klassifiziert, das ist, was ich glaube, Sie wollen. Im Allgemeinen können Sie die Kategorie eines Charakters mit unicodedata.category erhalten.

+3

+1. Aber besser, ".startswith ('M')" anstelle von ''M' 'hier zu verwenden. Ab 6.1 gibt es keine "M" Unterkategorien für irgendwelche Kategorien, aber es gibt keine Regel, die besagt, dass es in Zukunft keine geben kann. – abarnert

+0

@abarnert: Also sagst du, es ist besser, etwas zu verwenden, das in der Zukunft brechen könnte? – martineau

+0

@martineau: Nein, es ist besser, etwas zu verwenden, das in der Zukunft nicht bricht. Wenn eine Unterkategorie der Kategorie "M" hinzugefügt wird, wird sie zum Kombinieren von Marken verwendet. Wenn eine neue Unterkategorie "M" einer anderen Kategorie hinzugefügt wird, wird sie nicht zum Kombinieren von Markierungen verwendet. Also, die richtige Regel für die Kombination von Marken ist 'cat.startswith ('M')', nicht '' M 'in cat'. (Es ist nicht wahrscheinlich, dass es so weit kommt, weil sie keine neuen Unterkategorien hinzugefügt haben, die Buchstaben von Hauptkategorien gemeinsam benutzten, und leerten das einzige existierende 'LC'. Aber es ist nicht schaden, das Richtige zu tun und an der geringste potentielle Vorteil.) – abarnert

5

könnten Sie auch r'\p{M}' verwenden, die von regex module unterstützt:

import regex 

def remove_marks(text): 
    return regex.sub(ur"\p{M}+", "", text) 

Beispiel:

>>> print s 
A͋͠r͍̞̫̜t̼̭͞h́u̡̙̞̘rͬͣ̐ͮ 
>>> def remove_marks(text): 
...  return regex.sub(ur"\p{M}+", "", text) 
...  
... 
>>> print remove_marks(s) 
Arthur 

auf Ihrem Anwendungsfall Je ein Whitelist-Ansatz besser zB sein könnte, die Eingabe nur zu begrenzen, zu folgenden Zeichen:

>>> s.encode('ascii', 'ignore').decode('ascii') 
u'Arthur' 

Das Ergebnis hängt möglicherweise von der Unicode-Normalisierung ab, die im Text verwendet wird.

+0

Guter Punkt bei der Normalisierung - eine oder mehrere der Markierungen könnten in einen der Buchstaben geschrieben sein, in diesem Fall würden Sie diesen Buchstaben verlieren. Aber Sie können das lösen, indem Sie 'uncoredata.normalize ('NFD', s) .encode ('ascii', 'ignore') machen. Decode ('ascii')'. (Sie können stattdessen 'NFKD' verwenden, abhängig davon, ob Sie Dinge wie U + 2160 ('Ⅰ') erwarten und falls ja, ob Sie sie als kompatibles Äquivalent U + 0049 (' I') behandeln möchten) oder überspringe sie.) – abarnert

Verwandte Themen