In primo luogo, voglio essere d'accordo con gli altri sul fatto che la regex o le str.translate(...)
soluzioni basate siano le più performanti. Nel mio caso d'uso le prestazioni di questa funzione non erano significative, quindi volevo aggiungere idee che consideravo con quei criteri.
Il mio obiettivo principale era quello di generalizzare idee da alcune delle altre risposte in un'unica soluzione che potesse funzionare per stringhe che contenessero più di semplici parole regex (ovvero, inserire nella lista nera il sottoinsieme esplicito di caratteri di punteggiatura rispetto a caratteri di parole nella whitelist).
Si noti che, in qualsiasi approccio, si potrebbe anche considerare l'utilizzo string.punctuation
al posto di un elenco definito manualmente.
Opzione 1 - re.sub
Sono stato sorpreso di non vedere nessuna risposta finora utilizza re.sub (...) . Lo trovo un approccio semplice e naturale a questo problema.
import re
my_str = "Hey, you - what are you doing here!?"
words = re.split(r'\s+', re.sub(r'[,\-!?]', ' ', my_str).strip())
In questa soluzione, ho annidato la chiamata re.sub(...)
all'interno re.split(...)
- ma se le prestazioni sono fondamentali, compilare la regex all'esterno potrebbe essere utile - per il mio caso d'uso, la differenza non era significativa, quindi preferisco semplicità e leggibilità.
Opzione 2 - sostituzione str
Si tratta di alcune righe in più, ma ha il vantaggio di essere espandibile senza dover verificare se è necessario sfuggire a un determinato personaggio in regex.
my_str = "Hey, you - what are you doing here!?"
replacements = (',', '-', '!', '?')
for r in replacements:
my_str = my_str.replace(r, ' ')
words = my_str.split()
Sarebbe stato bello poter invece mappare str.replace sulla stringa, ma non penso che possa essere fatto con stringhe immutabili, e mentre la mappatura su un elenco di caratteri funzionerebbe, eseguendo ogni sostituzione su ogni carattere sembra eccessivo. (Modifica: vedere la prossima opzione per un esempio funzionale.)
Opzione 3 - functools.reduce
(In Python 2, reduce
è disponibile nello spazio dei nomi globale senza importarlo da functools.)
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()