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 re
oder sogar den regulären Ausdruck verwenden soll. Ich bin nicht sicher, wie ich das Regex-Muster v
richtig auf die eingehende Zeichenfolge (Zeile eines Buches) anwenden soll , um die neue Zeile ohne nicht alphanumerische Zeichen abzurufen.
Vorschläge?
v
ist 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.Antworten:
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.
quelle
^a-zA-Z
statt nur^a-zA-Z
a-zA-Z \n
. Ich versuche, einen regulären Ausdruck zu finden, der beide in einen zusammenfasst, aber das gewünschte Verhalten verwendet\w
oder\W
mir nicht gibt. Möglicherweise müssen Sie nur hinzufügen,\n
wenn dies der Fall ist.Wenn Sie Regex nicht verwenden möchten, können Sie es versuchen
''.join([i for i in s if i.isalpha()])
quelle
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 ""quelle
Versuchen:
s = ''.join(filter(str.isalnum, s))
Dadurch wird jedes Zeichen aus der Zeichenfolge entfernt, nur alphanumerische Zeichen beibehalten und eine Zeichenfolge daraus erstellt.
quelle
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
quelle
Es wird empfohlen, das PyPi-
regex
Modul 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 regex
oderpip3 install regex
), können Sie es verwendenimport 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
re
kann 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-regex
Bibliothek wird dringend empfohlen, um konsistente Ergebnisse zu erzielen .quelle