Quelle est la meilleure façon de supprimer tous les caractères non alphanumériques d'une chaîne en utilisant Python?
Les solutions présentées dans la variante PHP de cette question fonctionneront probablement avec quelques ajustements mineurs, mais ne me semblent pas très «pythoniques».
Pour mémoire, je ne veux pas seulement supprimer les points et les virgules (et autres signes de ponctuation), mais aussi les guillemets, les crochets, etc.
Réponses:
Je viens de chronométrer certaines fonctions par curiosité. Dans ces tests, je supprime les caractères non alphanumériques de la chaîne
string.printable
(partie dustring
module intégré). L'utilisation de compilé'[\W_]+'
etpattern.sub('', str)
s'est avérée être la plus rapide.la source
valid_characters = string.ascii_letters + string.digits
suiviejoin(ch for ch in string.printable if ch in valid_characters)
et c'était 6 microsecondes plus rapide que l'isalnum()
option. Toujours bien plus lent que l'expressionpattern.sub('', string.printable)
place - idiot d'appeler re.sub lorsque vous avez un objet RE! -).re.compile('[\W_]+', re.UNICODE)
pour le rendre unicode sûr.Expressions régulières à la rescousse:
la source
\W
gardera également les soulignements.Utilisez la méthode str.translate () .
En supposant que vous le ferez souvent:
(1) Une fois, créez une chaîne contenant tous les caractères que vous souhaitez supprimer:
(2) Chaque fois que vous voulez froncer une chaîne:
Le coût d'installation se compare probablement favorablement à re.compile; le coût marginal est bien inférieur:
Remarque: L' utilisation de string.printable comme données de référence confère au modèle «[\ W _] +» un avantage injuste ; tous les caractères non alphanumériques sont dans un seul paquet ... dans les données typiques, il y aurait plus d'une substitution à faire:
Voici ce qui se passe si vous donnez un peu plus de travail à re.sub:
la source
string.punctuation
Au lieu de''.join(c for c in map(chr, range(256)) if not c.isalnum())
str
objets mais pas pour lesunicode
objets..join()
?Tu pourrais essayer:
la source
la source
Que diriez-vous:
Cela fonctionne en utilisant la compréhension de liste pour produire une liste des caractères
InputString
s'ils sont présents dans les chaînes combinéesascii_letters
etdigits
. Il joint ensuite la liste en une chaîne.la source
Comme dérivé de quelques autres réponses ici, je propose un moyen très simple et flexible de définir un ensemble de caractères auquel vous souhaitez limiter le contenu d'une chaîne. Dans ce cas, j'autorise le tiret et le soulignement alphanumériques PLUS. Ajoutez ou supprimez simplement des caractères de mon
PERMITTED_CHARS
selon votre cas d'utilisation.la source
string.digits + string.ascii_letters + '_-'
.SPECIAL_CHARS = '_-'
puis utiliserstring.digits + string.ascii_letters + SPECIAL_CHARS
la source
e for e in sent
et vérifie via l'if e.isalpha()
instruction si le caractère actuel est un symbole alphabétique, si c'est le cas - le joint à lasent
variable viasent = "".join()
et tous les symboles non alphabétiques seront remplacés par""
(chaîne vide) car dejoin
fonction.la source
Synchronisation avec des chaînes aléatoires d'imprimables ASCII:
Résultat (Python 3.7):
str.maketrans
&str.translate
est le plus rapide, mais inclut tous les caractères non ASCII.re.compile
&pattern.sub
est plus lent, mais est en quelque sorte plus rapide que''.join
&filter
.la source
Si j'ai bien compris, la façon la plus simple est d'utiliser l'expression régulière car elle vous offre beaucoup de flexibilité, mais l'autre méthode simple consiste à utiliser pour le suivi de boucle est le code avec l'exemple, j'ai également compté l'occurrence de mot et stocké dans le dictionnaire ..
s'il vous plaît noter cela si cette réponse est utile!
la source