По-перше, я хочу погодитись з іншими, що str.translate(...)
рішення, засноване на регулярних виразів, є найбільш ефективним. Для мого використання виконання цієї функції не було суттєвим, тому я хотів додати ідеї, які я вважав за цими критеріями.
Моя головна мета полягала в тому, щоб узагальнити ідеї з деяких інших відповідей в одне рішення, яке могло б працювати для рядків, що містять більше, ніж просто регекс-слова (тобто чорний список явного підмножини знаків пунктуації та білих символів слова).
Зауважте, що при будь-якому підході можна також розглянути можливість використання string.punctuation
замість визначеного вручну списку.
Варіант 1 - повтор
Я був здивований, не побачивши жодної відповіді досі використовує re.sub (...) . Я вважаю простим і природним підхід до цієї проблеми.
import re
my_str = "Hey, you - what are you doing here!?"
words = re.split(r'\s+', re.sub(r'[,\-!?]', ' ', my_str).strip())
У цьому рішенні я вклав виклик re.sub(...)
всередину re.split(...)
- але якщо продуктивність критична, компіляція регулярного виразу зовні може бути корисним - для мого випадку використання різниця не була суттєвою, тому я віддаю перевагу простоті та читабельності.
Варіант 2 - str.replace
Це ще кілька рядків, але це має перевагу в розширенні, не перевіряючи, чи потрібно уникати певного символу в регулярному вираженні.
my_str = "Hey, you - what are you doing here!?"
replacements = (',', '-', '!', '?')
for r in replacements:
my_str = my_str.replace(r, ' ')
words = my_str.split()
Було б непогано мати можливість замістити str.replace замість рядка, але я не думаю, що це можна зробити за допомогою незмінних рядків, і хоча картування зі списком символів спрацювало б, запускаючи кожну заміну проти кожного символу звучить надмірно. (Редагувати: див. Наступний варіант для функціонального прикладу.)
Варіант 3 - functools.reduce
(У Python 2 reduce
доступний у глобальному просторі імен, не імпортуючи його з 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()