Primeiro, quero concordar com os outros que o regex ou as str.translate(...)
soluções baseadas são de melhor desempenho. Para o meu caso de uso, o desempenho dessa função não foi significativo, então eu queria adicionar idéias que considerasse com esse critério.
Meu principal objetivo era generalizar idéias de algumas das outras respostas em uma solução que pudesse funcionar para seqüências que contenham mais do que apenas palavras regex (ou seja, colocar na lista negra o subconjunto explícito de caracteres de pontuação versus caracteres de palavra na lista de permissões).
Observe que, em qualquer abordagem, também se pode considerar o uso string.punctuation
no lugar de uma lista definida manualmente.
Opção 1 - re.sub
Fiquei surpreso ao ver que nenhuma resposta até agora usa re.sub (...) . Acho que é uma abordagem simples e natural para esse problema.
import re
my_str = "Hey, you - what are you doing here!?"
words = re.split(r'\s+', re.sub(r'[,\-!?]', ' ', my_str).strip())
Nesta solução, aninhei a chamada para re.sub(...)
dentro re.split(...)
- mas se o desempenho for crítico, compilar o regex fora pode ser benéfico - para o meu caso de uso, a diferença não foi significativa, portanto prefiro simplicidade e legibilidade.
Opção 2 - str.replace
São mais algumas linhas, mas tem o benefício de ser expansível sem precisar verificar se você precisa escapar de um determinado caractere na 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()
Teria sido bom poder mapear o str.replace para a string, mas não acho que isso possa ser feito com strings imutáveis, e o mapeamento de uma lista de caracteres funcionaria, executando todas as substituições de cada personagem parece excessivo. (Editar: veja a próxima opção para um exemplo funcional.)
Opção 3 - functools.reduce
(No Python 2, reduce
está disponível no espaço de nomes global sem importá-lo das funções de ferramenta.)
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()