2014-10-26 18 views
6

mit Ich versuchte, die Emoji aus einem Unicode-Text twittern zu entfernen und 2.7 unter Verwendung von aus dem Ergebnis in Python druckenentfernen Unicode Emoji re in Python

myre = re.compile(u'[\u1F300-\u1F5FF\u1F600-\u1F64F\u1F680-\u1F6FF\u2600-\u26FF\u2700-\u27BF]+',re.UNICODE) 
print myre.sub('', text) 

aber es scheint fast alle Zeichen aus dem Text entfernt werden. Ich habe einige Antworten von anderen Posts überprüft, leider funktioniert keiner von ihnen hier. Habe ich etwas falsch gemacht in re.compile()?

hier ist ein Beispiel für die Ausgabe, dass alle Zeichen entfernt wurden:

“ ' //./” ! # # # … 
+0

Ist das Python 2? Python kann mit breiter oder enger Unicode-Unterstützung erstellt werden; Sie haben wahrscheinlich ein UCS-2-Build statt UCS-4, und das beeinflusst, was Sie mit regulären Ausdrücken tun können. –

+0

Und bitte geben Sie uns auch eine * Eingabe * Probe. –

+0

Ich konnte Ihr Problem reproduzieren, und ich habe auch gesehen, dass ein UCS-2-Build eine Exception auslöst, wenn Sie versuchen, den Ausdruck trotzdem zu kompilieren, so dass das hier nicht das Problem ist. –

Antwort

25

Sie nicht die korrekte Schreibweise für Nicht-BMP Unicode-Punkte verwenden; Sie wollen \U0001FFFF, ein HauptstadtU und 8 Ziffern verwenden:

myre = re.compile(u'[' 
    u'\U0001F300-\U0001F64F' 
    u'\U0001F680-\U0001F6FF' 
    u'\u2600-\u26FF\u2700-\u27BF]+', 
    re.UNICODE) 

als die ersten beiden Bereiche angrenzen:

myre = re.compile(u'[' 
    u'\U0001F300-\U0001F5FF' 
    u'\U0001F600-\U0001F64F' 
    u'\U0001F680-\U0001F6FF' 
    u'\u2600-\u26FF\u2700-\u27BF]+', 
    re.UNICODE) 

Dies kann reduziert werden.

Ihre Version (mit zusätzlichen Leerzeichen zur besseren Lesbarkeit) wurde festgelegt wird:

[\u1F30 0-\u1F5F F\u1F60 0-\u1F64 F\u1F68 0-\u1F6F F \u2600-\u26FF\u2700-\u27BF]+ 

Das ist, weil die \uxxxx Escape-Sequenz immer nur 4 hexadezimalen Ziffern nimmt, nicht 5.

Die größte dieser Bereiche ist 0-\u1F6F (also von der Ziffer 0 bis ), die eine sehr große swathe des Unicode-Standards abdeckt.

Der korrigierte Ausdruck funktioniert, sofern Sie eine UCS-4 breite Python ausführbare verwenden:

>>> import re 
>>> myre = re.compile(u'[' 
...  u'\U0001F300-\U0001F64F' 
...  u'\U0001F680-\U0001F6FF' 
...  u'\u2600-\u26FF\u2700-\u27BF]+', 
...  re.UNICODE) 
>>> myre.sub('', u'Some example text with a sleepy face: \U0001f62a') 
u'Some example text with a sleepy face: ' 

Der UCS-2 entspricht:

myre = re.compile(u'(' 
    u'\ud83c[\udf00-\udfff]|' 
    u'\ud83d[\udc00-\ude4f\ude80-\udeff]|' 
    u'[\u2600-\u26FF\u2700-\u27BF])+', 
    re.UNICODE) 

Sie können die zwei in das Skript kombinieren mit ein Ausnahmebehandler:

try: 
    # Wide UCS-4 build 
    myre = re.compile(u'[' 
     u'\U0001F300-\U0001F64F' 
     u'\U0001F680-\U0001F6FF' 
     u'\u2600-\u26FF\u2700-\u27BF]+', 
     re.UNICODE) 
except re.error: 
    # Narrow UCS-2 build 
    myre = re.compile(u'(' 
     u'\ud83c[\udf00-\udfff]|' 
     u'\ud83d[\udc00-\ude4f\ude80-\udeff]|' 
     u'[\u2600-\u26FF\u2700-\u27BF])+', 
     re.UNICODE) 
+3

Genau das, was ich oben kommentiert habe, aber ich bekomme 'sre_constants.error: bad character range' auf Python 2 Narrow Build. –

+0

@MarkTolonen: Ja, Sie können dies nur für einen Wide-Build verwenden, siehe [Python, konvertieren 4-Byte-Zeichen, um MySQL-Fehler zu vermeiden "Falscher String-Wert:"] (http://StackOverflow.com/q/12636489) für ein Ansatz (Sie müssen stattdessen die UTF-16-Ersatzpaare anpassen). –

+2

@MarkTolonen: eine UCS-2-Version hinzugefügt. –