Zunächst möchte ich zustimmen, dass die Regex- oder str.translate(...)
-basierten Lösungen am performantesten sind. In meinem Anwendungsfall war die Leistung dieser Funktion nicht signifikant, daher wollte ich Ideen hinzufügen, die ich unter diesem Kriterium in Betracht gezogen habe.
Mein Hauptziel war es, Ideen aus einigen der anderen Antworten zu verallgemeinern und in eine Lösung zu integrieren, die für Zeichenfolgen funktioniert, die mehr als nur Regex-Wörter enthalten (d.h. das Blacklisten des expliziten Untermengen von Satzzeichenzeichen gegen Whitelist-Wörterzeichen).
Beachten Sie, dass man in jedem Ansatz auch in Erwägung ziehen könnte, string.punctuation
anstelle einer manuell definierten Liste zu verwenden.
Option 1 - re.sub
Es hat mich überrascht, dass bisher noch keine Antwort re.sub(...) verwendet. Ich finde es einen einfachen und natürlichen Ansatz für dieses Problem.
import re
my_str = "Hey, you - what are you doing here!?"
words = re.split(r'\s+', re.sub(r'[,\-!?]', ' ', my_str).strip())
In dieser Lösung habe ich den Aufruf von re.sub(...)
innerhalb von re.split(...)
verschachtelt - aber wenn die Leistung entscheidend ist, könnte es von Vorteil sein, das Regex außerhalb zu kompilieren. Für meinen Anwendungsfall war der Unterschied nicht signifikant, daher bevorzuge ich Einfachheit und Lesbarkeit.
Option 2 - str.replace
Es sind ein paar Zeilen mehr, aber es hat den Vorteil, ohne Überprüfung, ob ein bestimmtes Zeichen in Regex maskiert werden muss, erweiterbar zu sein.
my_str = "Hey, you - what are you doing here!?"
replacements = (',', '-', '!', '?')
for r in replacements:
my_str = my_str.replace(r, ' ')
words = my_str.split()
Es wäre schön gewesen, das str.replace direkt auf die Zeichenfolge zu mappen, aber ich glaube nicht, dass dies mit unveränderlichen Strings möglich ist. Und während das Mappen gegen eine Liste von Zeichen funktionieren würde, klingt es übertrieben, jede Ersetzung gegen jedes Zeichen auszuführen. (Edit: Siehe nächste Option für ein funktionales Beispiel.)
Option 3 - functools.reduce
(In Python 2 ist reduce
im globalen Namespace verfügbar, ohne es aus functools zu importieren.)
import functools
my_str = "Hey, you - what are you doing here!?"
replacements = (',', '-', '!', '?')
my_str = functools.reduce(lambda s, sep: s.replace(sep, ' '), replacements, my_str)
words = my_str.split()
7 Stimmen
docs.python.org/library/re.html
13 Stimmen
Python's
str.split()
funktioniert auch ohne Argumente überhaupt