Po pierwsze, chcę zgodzić się z innymi, że regex lub str.translate(...)
oparte na nim rozwiązania są najbardziej wydajne. W moim przypadku użycie tej funkcji nie było znaczące, dlatego chciałem dodać pomysły, które wziąłem pod uwagę przy tych kryteriach.
Moim głównym celem było uogólnienie pomysłów z niektórych innych odpowiedzi w jedno rozwiązanie, które może pracować dla ciągów zawierających więcej niż tylko słowa wyrażenia regularnego (tj. Umieszczenie na czarnej liście wyraźnego podzbioru znaków interpunkcyjnych w porównaniu do znaków słów z białej listy).
Zauważ, że w każdym podejściu można również rozważyć użycie string.punctuation
zamiast ręcznie zdefiniowanej listy.
Opcja 1 - re
Byłem zaskoczony, że do tej pory nie otrzymałem odpowiedzi, używa re.sub (...) . Uważam to za proste i naturalne podejście do tego problemu.
import re
my_str = "Hey, you - what are you doing here!?"
words = re.split(r'\s+', re.sub(r'[,\-!?]', ' ', my_str).strip())
W tym rozwiązaniu zagnieździłem wezwanie do re.sub(...)
wewnątrz re.split(...)
- ale jeśli wydajność jest krytyczna, kompilacja wyrażenia regularnego na zewnątrz może być korzystna - w moim przypadku różnica nie była znacząca, więc wolę prostotę i czytelność.
Opcja 2 - wymiana str
Jest to jeszcze kilka wierszy, ale ma tę zaletę, że można ją rozbudowywać bez konieczności sprawdzania, czy trzeba uciec pewnej postaci w wyrażeniu regularnym.
my_str = "Hey, you - what are you doing here!?"
replacements = (',', '-', '!', '?')
for r in replacements:
my_str = my_str.replace(r, ' ')
words = my_str.split()
Byłoby miło móc zamiast tego zamapować str .replace na ciąg, ale nie sądzę, że można tego dokonać za pomocą niezmiennych ciągów, a podczas mapowania na listę znaków zadziałałoby, uruchamiając każdą zamianę na każdym znaku brzmi nadmiernie. (Edycja: zobacz następną opcję dla funkcjonalnego przykładu.)
Opcja 3 - funkools.reduce
(W Python 2 reduce
jest dostępny w globalnej przestrzeni nazw bez importowania go z funools.)
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()