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?
Du point de vue de l'efficacité, vous n'allez pas battre
s.translate(None, string.punctuation)
Pour les versions supérieures de Python, utilisez le code suivant:
s.translate(str.maketrans('', '', string.punctuation))
Il effectue des opérations de chaîne brutes en C avec une table de correspondance - il n'y a pas grand-chose qui batte celui-ci mais écrit votre propre code C.
Si la vitesse ne vous inquiète pas, une autre option est:
exclude = set(string.punctuation)
s = ''.join(ch for ch in s if ch not in exclude)
Ceci est plus rapide qu'à chaque caractère, mais ne fonctionne pas aussi bien que les approches python non pures telles que les expressions rationnelles ou string.translate, comme vous pouvez le constater avec les timings ci-dessous. Pour ce type de problème, le faire à un niveau aussi bas que possible rapporte.
Code de chronométrage:
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
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)
Dans le code ci-dessus, nous substituons (re.sub) tous les NON [caractères alphanumériques (\ w) et les espaces (\ s)] par une chaîne vide.
Par conséquent . et ? la ponctuation ne sera pas présente dans la variable 's' après avoir exécuté la variable s avec regex.
Pour la commodité de l’utilisation, je résume la note de ponctuation de striping d’une chaîne dans Python 2 et Python 3. Veuillez vous reporter à d’autres réponses pour une 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
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
myString.translate(None, string.punctuation)
J'utilise habituellement quelque chose comme ça:
>>> s = "string. With. Punctuation?" # Sample string
>>> import string
>>> for c in string.punctuation:
... s= s.replace(c,"")
...
>>> s
'string With Punctuation'
string.punctuation
est ASCII seulement! Une méthode plus correcte (mais aussi beaucoup plus lente) consiste à 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
Pas nécessairement plus simple, mais d'une manière différente, si vous connaissez mieux la famille re.
import re, string
s = "string. With. Punctuation?" # Sample string
out = re.sub('[%s]' % re.escape(string.punctuation), '', s)
string.punctuation
manque des charges de signes de ponctuation couramment utilisés dans le monde réel. Que diriez-vous d'une solution qui fonctionne pour la ponctuation non-ASCII?
import regex
s = u"string. With. Some・Really Weird、Non?ASCII。 「(Punctuation)」?"
remove = regex.compile(ur'[\p{C}|\p{M}|\p{P}|\p{S}|\p{Z}]+', regex.UNICODE)
remove.sub(u" ", s).strip()
Personnellement, je pense que c'est le meilleur moyen de supprimer la ponctuation d'une chaîne en Python car:
\{S}
si vous souhaitez supprimer la ponctuation, tout en conservant des symboles tels que $
.\{Pd}
ne supprimera que les tirets.Ceci utilise les propriétés de caractère Unicode, qui vous pouvez en savoir plus sur Wikipedia .
Pour Python 3 str
ou Python 2 unicode
name__, str.translate()
ne prend qu'un dictionnaire; Les points de code (entiers) sont recherchés dans ce mappage et tout ce qui est mappé à None
est supprimé.
Pour supprimer (certains?) Ponctuation, utilisez:
import string
remove_punct_map = dict.fromkeys(map(ord, string.punctuation))
s.translate(remove_punct_map)
La méthode dict.fromkeys()
class rend la création du mappage facile, en définissant toutes les valeurs sur None
en fonction de la séquence de clés.
Pour supprimer toute la ponctuation, et pas seulement ASCII ponctuation, votre tableau doit être un peu plus grand; voir réponse de J.F. Sebastian (version Python 3):
import unicodedata
import sys
remove_punct_map = dict.fromkeys(i for i in range(sys.maxunicode)
if unicodedata.category(chr(i)).startswith('P'))
Ce n'est peut-être pas la meilleure solution, mais voici comment je l'ai fait.
import string
f = lambda x: ''.join([i for i in x if i not in string.punctuation])
Voici une fonction que j'ai écrite. Ce n'est pas très efficace, mais c'est simple et vous pouvez ajouter ou supprimer toute ponctuation que vous désirez:
def stripPunc(wordList):
"""Strips punctuation from list of words"""
puncList = [".",";",":","!","?","/","\\",",","#","@","$","&",")","(","\""]
for punc in puncList:
for Word in wordList:
wordList=[Word.replace(punc,'') for Word in wordList]
return wordList
Je n'ai pas encore vu cette réponse. Il suffit d'utiliser un regex; il supprime tous les caractères autres que les mots Word (\w
) et les caractères numériques (\d
), suivis d'un caractère blanc (\s
):
import re
s = "string. With. Punctuation?" # Sample string
out = re.sub(ur'[^\w\d\s]+', '', s)
Voici un one-liner pour Python 3.5:
import string
"l*ots! o(f. p@u)n[c}t]u[a'ti\"on#$^?/".translate(str.maketrans({a:None for a in string.punctuation}))
À titre de mise à jour, j’ai réécrit l’exemple @Brian dans Python 3 et ya apporté des modifications pour déplacer l’étape de compilation regex à l’intérieur de la fonction. Ma pensée était de chronométrer chaque étape nécessaire pour que la fonction fonctionne. Peut-être utilisez-vous l'informatique distribuée et ne pouvez-vous pas partager un objet regex entre vos travailleurs et devez-vous avoir l'étape re.compile
à chaque travailleur? Aussi, j'étais curieux de chronométrer deux implémentations différentes de maketrans pour Python 3
table = str.maketrans({key: None for key in string.punctuation})
contre
table = str.maketrans('', '', string.punctuation)
De plus, j'ai ajouté une autre méthode pour utiliser set, où je tire parti de la fonction d'intersection pour réduire le nombre d'itérations.
C'est le code complet:
import re, string, timeit
s = "string. With. Punctuation"
def test_set(s):
exclude = set(string.punctuation)
return ''.join(ch for ch in s if ch not in exclude)
def test_set2(s):
_punctuation = set(string.punctuation)
for punct in set(s).intersection(_punctuation):
s = s.replace(punct, ' ')
return ' '.join(s.split())
def test_re(s): # From Vinko's solution, with fix.
regex = re.compile('[%s]' % re.escape(string.punctuation))
return regex.sub('', s)
def test_trans(s):
table = str.maketrans({key: None for key in string.punctuation})
return s.translate(table)
def test_trans2(s):
table = str.maketrans('', '', string.punctuation)
return(s.translate(table))
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("sets2 :",timeit.Timer('f(s)', 'from __main__ import s,test_set2 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("translate2 :",timeit.Timer('f(s)', 'from __main__ import s,test_trans2 as f').timeit(1000000))
print("replace :",timeit.Timer('f(s)', 'from __main__ import s,test_repl as f').timeit(1000000))
Voici mes résultats:
sets : 3.1830138750374317
sets2 : 2.189873124472797
regex : 7.142953420989215
translate : 4.243278483860195
translate2 : 2.427158243022859
replace : 4.579746678471565
Voici une solution sans regex.
import string
input_text = "!where??and!!or$$then:)"
punctuation_replacer = string.maketrans(string.punctuation, ' '*len(string.punctuation))
print ' '.join(input_text.translate(punctuation_replacer).split()).strip()
Output>> where and or then
import re
s = "string. With. Punctuation?" # Sample string
out = re.sub(r'[^a-zA-Z0-9\s]', '', s)
>>> s = "string. With. Punctuation?"
>>> s = re.sub(r'[^\w\s]','',s)
>>> re.split(r'\s*', s)
['string', 'With', 'Punctuation']
Un one-liner pourrait être utile dans des cas peu sévères:
''.join([c for c in s if c.isalnum() or c.isspace()])
Effectuez une recherche et remplacez à l’aide des fonctions regex, comme indiqué ici. . Si vous devez effectuer l'opération à plusieurs reprises, vous pouvez conserver une copie compilée du motif regex (votre ponctuation), ce qui accélérera un peu les choses.
with open('one.txt','r')as myFile:
str1=myFile.read()
print(str1)
punctuation = ['(', ')', '?', ':', ';', ',', '.', '!', '/', '"', "'"]
for i in punctuation:
str1 = str1.replace(i," ")
myList=[]
myList.extend(str1.split(" "))
print (str1)
for i in myList:
print(i,end='\n')
print ("____________")
#FIRST METHOD
#Storing all punctuations in a variable
punctuation='!?,.:;"\')(_-'
newstring='' #Creating empty string
Word=raw_input("Enter string: ")
for i in Word:
if(i not in punctuation):
newstring+=i
print "The string without punctuation is",newstring
#SECOND METHOD
Word=raw_input("Enter string: ")
punctuation='!?,.:;"\')(_-'
newstring=Word.translate(None,punctuation)
print "The string without punctuation is",newstring
#Output for both methods
Enter string: hello! welcome -to_python(programming.language)??,
The string without punctuation is: hello welcome topythonprogramminglanguage
Pourquoi aucun de vous ne l'utilise?
''.join(filter(str.isalnum, s))
Trop lent?