Enlever tout sauf les caractères alphanumériques d'une chaîne en Python
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 de PHP de cette question fonctionneront probablement avec quelques ajustements mineurs, mais ne me semblent pas très "pythonic".
pour information, Je ne veux pas seulement rayer les périodes et les virgules (et autres signes de ponctuation), mais aussi les citations, les parenthèses, etc.
7 réponses
je viens de chronométrer quelques fonctions par curiosité. Dans ces tests, je supprime les caractères non alphanumériques de la chaîne de caractères string.printable
(qui fait partie du module intégré string
).
$ python -m timeit -s \
"import string" \
"''.join(ch for ch in string.printable if ch.isalnum())"
10000 loops, best of 3: 57.6 usec per loop
$ python -m timeit -s \
"import string" \
"filter(str.isalnum, string.printable)"
10000 loops, best of 3: 37.9 usec per loop
$ python -m timeit -s \
"import re, string" \
"re.sub('[\W_]', '', string.printable)"
10000 loops, best of 3: 27.5 usec per loop
$ python -m timeit -s \
"import re, string" \
"re.sub('[\W_]+', '', string.printable)"
100000 loops, best of 3: 15 usec per loop
$ python -m timeit -s \
"import re, string; pattern = re.compile('[\W_]+')" \
"pattern.sub('', string.printable)"
100000 loops, best of 3: 11.2 usec per loop
expressions régulières à la rescousse:
import re
re.sub(r'\W+', '', your_string)
par définition de Python
'\W
= =[^a-zA-Z0-9_]
, ce qui exclut tous lesnumbers
,letters
et_
utiliser le str.translate() la méthode.
présumant que vous le ferez souvent:
(1) Une fois, créez une chaîne de caractères contenant tous les caractères que vous souhaitez supprimer:
delchars = ''.join(c for c in map(chr, range(256)) if not c.isalnum())
(2) chaque fois que vous voulez broyer une corde:
scrunched = s.translate(None, delchars)
le coût d'installation se compare probablement favorablement avec re.le coût marginal est beaucoup plus faible:
C:\junk>\python26\python -mtimeit -s"import string;d=''.join(c for c in map(chr,range(256)) if not c.isalnum());s=string.printable" "s.translate(None,d)"
100000 loops, best of 3: 2.04 usec per loop
C:\junk>\python26\python -mtimeit -s"import re,string;s=string.printable;r=re.compile(r'[\W_]+')" "r.sub('',s)"
100000 loops, best of 3: 7.34 usec per loop
Note: utilisant une chaîne de caractères.imprimable comme données de référence donne au modèle '[\W_]+ ' un avantage indu ; tous les caractères non-alphanumériques sont dans un groupe ... dans les données Types, il y aurait plus d'une substitution à faire:
C:\junk>\python26\python -c "import string; s = string.printable; print len(s),repr(s)"
100 '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;=>?@[\]^_`{|}~ \t\n\r\x0b\x0c'
voici ce qui se passe si vous donnez re.sous un peu plus de travail à faire:
C:\junk>\python26\python -mtimeit -s"d=''.join(c for c in map(chr,range(256)) if not c.isalnum());s='foo-'*25" "s.translate(None,d)"
1000000 loops, best of 3: 1.97 usec per loop
C:\junk>\python26\python -mtimeit -s"import re;s='foo-'*25;r=re.compile(r'[\W_]+')" "r.sub('',s)"
10000 loops, best of 3: 26.4 usec per loop
Vous pouvez essayer:
print ''.join(ch for ch in some_string if ch.isalnum())
>>> import re
>>> string = "Kl13@£$%[};'\""
>>> pattern = re.compile('\W')
>>> string = re.sub(pattern, '', string)
>>> print string
Kl13
Que Diriez-vous de:
def ExtractAlphanumeric(InputString):
from string import ascii_letters, digits
return "".join([ch for ch in InputString if ch in (ascii_letters + digits)])
cela fonctionne en utilisant la compréhension de liste pour produire une liste des caractères dans InputString
s'ils sont présents dans les chaînes combinées ascii_letters
et digits
. Il réunit ensuite la liste en une chaîne.
comme un spin off de quelques autres réponses ici, j'offre une façon vraiment simple et flexible pour définir un ensemble de caractères que vous voulez limiter le contenu d'une chaîne de caractères. Dans ce cas, j'autorise les caractères alphanumériques PLUS le tiret et le trait de soulignement. Il suffit d'ajouter ou de supprimer des caractères de mon PERMITTED_CHARS
comme convient à votre cas d'utilisation.
PERMITTED_CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-"
someString = "".join(c for c in someString if c in PERMITTED_CHARS)