Tout d'abord, je veux convenir avec d'autres que les regex ou les str.translate(...)
solutions basées sont les plus performantes. Pour mon cas d'utilisation, les performances de cette fonction n'étaient pas significatives, j'ai donc voulu ajouter des idées que j'ai considérées avec ces critères.
Mon objectif principal était de généraliser les idées de certaines des autres réponses en une solution qui pourrait fonctionner pour des chaînes contenant plus que des mots regex (c.-à-d., Mettre sur liste noire le sous-ensemble explicite de caractères de ponctuation par rapport aux caractères de mots sur liste blanche).
Notez que, dans toute approche, on pourrait également envisager d'utiliser string.punctuation
à la place d'une liste définie manuellement.
Option 1 - re.sub
J'ai été surpris de ne pas avoir trouvé de réponse jusqu'à présent sur re.sub (...) . Je trouve que c'est une approche simple et naturelle de ce problème.
import re
my_str = "Hey, you - what are you doing here!?"
words = re.split(r'\s+', re.sub(r'[,\-!?]', ' ', my_str).strip())
Dans cette solution, j'ai imbriqué l'appel à l' re.sub(...)
intérieur re.split(...)
- mais si les performances sont essentielles, la compilation de l'expression régulière à l'extérieur pourrait être bénéfique - pour mon cas d'utilisation, la différence n'était pas significative, donc je préfère la simplicité et la lisibilité.
Option 2 - remplacement str.
Il s'agit de quelques lignes supplémentaires, mais cela a l'avantage d'être extensible sans avoir à vérifier si vous devez échapper à un certain personnage dans 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()
Cela aurait été bien de pouvoir mapper le str.replace à la chaîne à la place, mais je ne pense pas que cela puisse être fait avec des chaînes immuables, et tout en mappant avec une liste de caractères fonctionnerait, exécuter chaque remplacement contre chaque caractère semble excessif. (Modifier: Voir l'option suivante pour un exemple fonctionnel.)
Option 3 - functools.reduce
(En Python 2, reduce
est disponible dans l'espace de noms global sans l'importer depuis 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()