Python, entfernen Sie alle Nicht-Alphabet-Zeichen aus der Zeichenfolge

89

Ich schreibe ein Python MapReduce-Wortzählprogramm. Das Problem ist, dass in den Daten viele Nicht-Alphabet-Zeichen verstreut sind. Ich habe diesen Beitrag gefunden. Ich habe alles außer alphanumerischen Zeichen aus einer Zeichenfolge in Python entfernt, die eine gute Lösung mit Regex zeigt, aber ich bin nicht sicher, wie ich sie implementieren soll

def mapfn(k, v):
    print v
    import re, string 
    pattern = re.compile('[\W_]+')
    v = pattern.match(v)
    print v
    for w in v.split():
        yield w, 1

Ich fürchte, ich bin mir nicht sicher, wie ich die Bibliothek reoder sogar den regulären Ausdruck verwenden soll. Ich bin nicht sicher, wie ich das Regex-Muster vrichtig auf die eingehende Zeichenfolge (Zeile eines Buches) anwenden soll , um die neue Zeile ohne nicht alphanumerische Zeichen abzurufen.

Vorschläge?

KDecker
quelle
vist eine ganze Zeile eines Buches (speziell Moby Dick), ich gehe Wort für Wort, nicht Char für Char. Einige Wörter haben möglicherweise ein "," am Ende, so dass "Empörung" nicht mit "Empörung" übereinstimmt.
KDecker
Lolx - hast du die gleiche Heimübung vor dem Interview bekommen wie ich? Finden Sie die 50 am häufigsten verwendeten Wörter in Moby Dick und geben Sie deren Häufigkeit an. Ich habe es in C ++, IIRC gemacht
Mawg sagt, Monica
1
@Mawg Es war eine Übung in meiner "Cloud Computing" -Klasse.
KDecker

Antworten:

127

Verwenden re.sub

import re

regex = re.compile('[^a-zA-Z]')
#First parameter is the replacement, second parameter is your input string
regex.sub('', 'ab3d*E')
#Out: 'abdE'

Alternativ, wenn Sie nur einen bestimmten Zeichensatz entfernen möchten (da ein Apostroph in Ihrer Eingabe möglicherweise in Ordnung ist ...)

regex = re.compile('[,\.!?]') #etc.
limasxgoesto0
quelle
Hmm, ich kann es durchaus aufspüren, aber was ist mit dem Muster, um alle nicht-alphanumerischen Zeichen außer Leerzeichen zu entfernen?
KDecker
1
Fügen Sie Ihrer Sammlungsklasse einfach ein Leerzeichen hinzu. dh ^a-zA-Z statt nur^a-zA-Z
limasxgoesto0
Es sei denn, Sie machen sich in diesem Fall auch Sorgen um Zeilenumbrüche a-zA-Z \n. Ich versuche, einen regulären Ausdruck zu finden, der beide in einen zusammenfasst, aber das gewünschte Verhalten verwendet \woder \Wmir nicht gibt. Möglicherweise müssen Sie nur hinzufügen, \nwenn dies der Fall ist.
limasxgoesto0
Ahh, der Newline-Char. Dort liegen meine Probleme, ich habe meine Ergebnisse mit den angegebenen Ergebnissen verglichen und war immer noch weg. Ich denke das ist mein Problem! Danke // Hmm, ich habe es mit dem Newline-Zeichen versucht, gleiche Ergebnisse, ich denke, es gibt noch einen, den ich vermisse .. // Duhhh ... Groß- und Kleinschreibung ... // Danke für all die Hilfe, funktioniert jetzt perfekt!
KDecker
48

Wenn Sie Regex nicht verwenden möchten, können Sie es versuchen

''.join([i for i in s if i.isalpha()])
Bisschen
quelle
Wie mache ich mit? mit '' .join? Druck s bekommt nur ein Filterobjekt
PirateApp
Wow, das habe ich gesucht. Dies berücksichtigt Kanji, Hiragana, Katakana usw. Kudos
root163
34

Mit der Funktion re.sub () können Sie folgende Zeichen entfernen:

>>> import re
>>> re.sub("[^a-zA-Z]+", "", "ABC12abc345def")
'ABCabcdef'

re.sub (MATCH PATTERN, STRING ERSETZEN, STRING TO SEARCH)

  • "[^a-zA-Z]+" - Suchen Sie nach einer Gruppe von Zeichen, die NICHT a-zA-z sind.
  • "" - Ersetzen Sie die übereinstimmenden Zeichen durch ""
Kevin
quelle
Beachten Sie, dass dadurch auch akzentuierte Buchstaben entfernt werden: ãâàáéèçõ usw.
Brad Ahrens
18

Versuchen:

s = ''.join(filter(str.isalnum, s))

Dadurch wird jedes Zeichen aus der Zeichenfolge entfernt, nur alphanumerische Zeichen beibehalten und eine Zeichenfolge daraus erstellt.

Don
quelle
1
Diese Antwort könnte viel mehr Erklärungen und Links zu relevanten Dokumentationen gebrauchen.
pdoherty926
3

Die schnellste Methode ist Regex

#Try with regex first
t0 = timeit.timeit("""
s = r2.sub('', st)

""", setup = """
import re
r2 = re.compile(r'[^a-zA-Z0-9]', re.MULTILINE)
st = 'abcdefghijklmnopqrstuvwxyz123456789!@#$%^&*()-=_+'
""", number = 1000000)
print(t0)

#Try with join method on filter
t0 = timeit.timeit("""
s = ''.join(filter(str.isalnum, st))

""", setup = """
st = 'abcdefghijklmnopqrstuvwxyz123456789!@#$%^&*()-=_+'
""",
number = 1000000)
print(t0)

#Try with only join
t0 = timeit.timeit("""
s = ''.join(c for c in st if c.isalnum())

""", setup = """
st = 'abcdefghijklmnopqrstuvwxyz123456789!@#$%^&*()-=_+'
""", number = 1000000)
print(t0)


2.6002226710006653 Method 1 Regex
5.739747313000407 Method 2 Filter + Join
6.540099570000166 Method 3 Join
PirateApp
quelle
0

Es wird empfohlen, das PyPi- regexModul zu verwenden, wenn Sie bestimmte Unicode-Eigenschaftsklassen abgleichen möchten . Diese Bibliothek hat sich auch als stabiler erwiesen, insbesondere bei der Verarbeitung großer Texte, und liefert konsistente Ergebnisse für verschiedene Python-Versionen. Alles was Sie tun müssen, ist es auf dem neuesten Stand zu halten.

Wenn Sie es installieren (mit pip intall regexoder pip3 install regex), können Sie es verwenden

import regex
print ( regex.sub(r'\P{L}+', '', 'ABCŁąć1-2!Абв3§4“5def”') )
// => ABCŁąćАбвdef

um alle Teile von 1 oder mehr Zeichen außer Unicode-Buchstaben aus zu entfernen text. Sehen Sie sich eine Online-Python-Demo an . Sie können auch verwenden "".join(regex.findall(r'\p{L}+', 'ABCŁąć1-2!Абв3§4“5def”')), um das gleiche Ergebnis zu erhalten.

In Python rekann man das [^\W\d_]Konstrukt verwenden (mit einem Unicode-Buchstaben übereinstimmen ? ) , Um mit einem Unicode-Buchstaben übereinzustimmen .

Um alle Nicht-Buchstaben-Zeichen zu entfernen, können Sie entweder alle Buchstaben abgleichen und die Ergebnisse verbinden:

result = "".join(re.findall(r'[^\W\d_]', text))

Oder entfernen Sie alle Zeichen außer denen, die mit [^\W\d_]: übereinstimmen.

result = re.sub(r'([^\W\d_])|.', r'\1', text, re.DOTALL)

Sehen Sie sich die Regex-Demo online an . Es kann jedoch vorkommen , dass Sie in verschiedenen Python-Versionen inkonsistente Ergebnisse erhalten, da sich der Unicode-Standard weiterentwickelt und die Anzahl der Zeichen, mit denen übereinstimmen \w, von der Python-Version abhängt. Die Verwendung der PyPi- regexBibliothek wird dringend empfohlen, um konsistente Ergebnisse zu erzielen .

Wiktor Stribiżew
quelle