Question Meilleure façon de supprimer la ponctuation d'une chaîne en Python


Il semble qu'il devrait y avoir un moyen plus simple que:

import string
s = "string. With. Punctuation?" # Sample string 
out = s.translate(string.maketrans("",""), string.punctuation)

Y a-t-il?


446
2017-11-05 17:30


origine


Réponses:


Du point de vue de l'efficacité, vous n'allez pas battre

s.translate(None, string.punctuation)

Il effectue des opérations de chaîne brutes en C avec une table de recherche - il n'y a pas grand chose qui bat cela, mais en écrivant votre propre code C.

Si la vitesse n'est pas un souci, une autre option est:

exclude = set(string.punctuation)
s = ''.join(ch for ch in s if ch not in exclude)

Ceci est plus rapide que s.replace avec chaque caractère, mais ne fonctionnera pas aussi bien que les approches python non pures telles que les regex ou string.translate, comme vous pouvez le voir dans les timings ci-dessous. Pour ce type de problème, le faire à un niveau aussi bas que possible est payant.

Code de temps:

import re, string, timeit

s = "string. With. Punctuation"
exclude = set(string.punctuation)
table = string.maketrans("","")
regex = re.compile('[%s]' % re.escape(string.punctuation))

def test_set(s):
    return ''.join(ch for ch in s if ch not in exclude)

def test_re(s):  # From Vinko's solution, with fix.
    return regex.sub('', s)

def test_trans(s):
    return s.translate(table, string.punctuation)

def test_repl(s):  # From S.Lott's solution
    for c in string.punctuation:
        s=s.replace(c,"")
    return s

print "sets      :",timeit.Timer('f(s)', 'from __main__ import s,test_set as f').timeit(1000000)
print "regex     :",timeit.Timer('f(s)', 'from __main__ import s,test_re as f').timeit(1000000)
print "translate :",timeit.Timer('f(s)', 'from __main__ import s,test_trans as f').timeit(1000000)
print "replace   :",timeit.Timer('f(s)', 'from __main__ import s,test_repl as f').timeit(1000000)

Cela donne les résultats suivants:

sets      : 19.8566138744
regex     : 6.86155414581
translate : 2.12455511093
replace   : 28.4436721802

627
2017-11-05 18:36



Les expressions régulières sont assez simples, si vous les connaissez.

import re
s = "string. With. Punctuation?"
s = re.sub(r'[^\w\s]','',s)

77
2018-05-28 18:47



myString.translate(None, string.punctuation)

47
2018-03-08 15:19



Pour la commodité de l'utilisation, je résume la note de ponctuation par bandes d'une chaîne dans Python 2 et Python 3. Veuillez vous référer aux autres réponses pour la description détaillée.


Python 2

import string

s = "string. With. Punctuation?"
table = string.maketrans("","")
new_s = s.translate(table, string.punctuation)      # Output: string without punctuation

Python 3

import string

s = "string. With. Punctuation?"
table = str.maketrans({key: None for key in string.punctuation})
new_s = s.translate(table)                          # Output: string without punctuation

36
2018-05-14 01:57



J'utilise habituellement quelque chose comme ceci:

>>> s = "string. With. Punctuation?" # Sample string
>>> import string
>>> for c in string.punctuation:
...     s= s.replace(c,"")
...
>>> s
'string With Punctuation'

21
2017-11-05 17:41



string.punctuation est ASCII seulement! Une manière plus correcte (mais aussi beaucoup plus lente) est d'utiliser le module unicodedata:

# -*- coding: utf-8 -*-
from unicodedata import category
s = u'String — with -  «punctation »...'
s = ''.join(ch for ch in s if category(ch)[0] != 'P')
print 'stripped', s

19
2017-09-01 09:29



Pas nécessairement plus simple, mais d'une manière différente, si vous êtes plus familier avec la famille re.

import re, string
s = "string. With. Punctuation?" # Sample string 
out = re.sub('[%s]' % re.escape(string.punctuation), '', s)

17
2017-11-05 17:39