Question

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?

Était-ce utile?

La solution

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înes brutes en C avec une table de correspondance - rien n’est plus efficace que l’écriture de 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 que chaque caractère, mais ne fonctionne pas aussi bien que les approches python non pures, telles que les regex 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

Autres conseils

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) 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 séparation de ponctuation 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 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
myString.translate(None, string.punctuation)

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'

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 ê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)

Pour les valeurs str de Python 3 ou unicode , str.translate () ne prend qu'un dictionnaire; Les points de code (entiers) sont recherchés dans ce mappage et tout élément mappé à Aucun est supprimé.

Pour supprimer (certains?) ponctuation, utilisez:

import string

remove_punct_map = dict.fromkeys(map(ord, string.punctuation))
s.translate(remove_punct_map)

La classe dict.fromkeys () La méthode facilite la création du mappage en définissant toutes les valeurs sur Aucun en fonction de la séquence de clés.

Pour supprimer toutes la ponctuation, et pas seulement la ponctuation ASCII, votre table doit être un peu plus grande; voir J.F. Réponse de 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'))

string.punctuation manque des charges de signes de ponctuation couramment utilisés dans le monde réel. Pourquoi pas 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:

  • Cela supprime toute ponctuation Unicode
  • Il est facilement modifiable, par exemple vous pouvez supprimer le \ {S} si vous souhaitez supprimer la ponctuation, tout en conservant des symboles tels que $ .
  • Vous pouvez obtenir des informations très précises sur ce que vous souhaitez conserver et sur ce que vous souhaitez supprimer. Par exemple, \ {Pd} ne supprimera que les tirets.
  • Cette expression rationnelle normalise également les espaces. Il mappe les onglets, les retours chariots et d’autres bizarreries sur de beaux espaces simples.

Ceci utilise les propriétés de caractère Unicode, qui vous pouvez en savoir plus sur Wikipedia .

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 = [".",";",":","!","?","/","\\",",","#","@","<*>quot;,"&",")","(","\""]
    for punc in puncList:
        for word in wordList:
            wordList=[word.replace(punc,'') for word in wordList]
    return wordList

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}))

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 ( \ w ) et les caractères numériques ( \ d ), suivis d'un espace ( \ s ):

import re
s = "string. With. Punctuation?" # Sample string 
out = re.sub(ur'[^\w\d\s]+', '', s)

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
  • Remplace les ponctuations par des espaces
  • Remplacez les espaces multiples entre les mots par un seul espace
  • Supprimez les espaces de fin, le cas échéant avec strip ()

Comme 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, vous ne pouvez pas partager d’objet regex entre vos employés et vous devez définir l’étape re.compile sur chaque employé. De plus, 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})

vs

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.

Ceci 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
>>> s = "string. With. Punctuation?"
>>> s = re.sub(r'[^\w\s]','',s)
>>> re.split(r'\s*', s)


['string', 'With', 'Punctuation']
import re
s = "string. With. Punctuation?" # Sample string 
out = re.sub(r'[^a-zA-Z0-9\s]', '', s)

Une seule ligne pourrait être utile dans des cas peu sévères:

''.join([c for c in s if c.isalnum() or c.isspace()])
#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
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 ("____________")

Supprimez les mots vides du fichier texte à l'aide de Python

print('====THIS IS HOW TO REMOVE STOP WORS====')

with open('one.txt','r')as myFile:

    str1=myFile.read()

    stop_words ="not", "is", "it", "By","between","This","By","A","when","And","up","Then","was","by","It","If","can","an","he","This","or","And","a","i","it","am","at","on","in","of","to","is","so","too","my","the","and","but","are","very","here","even","from","them","then","than","this","that","though","be","But","these"

    myList=[]

    myList.extend(str1.split(" "))

    for i in myList:

        if i not in stop_words:

            print ("____________")

            print(i,end='\n')

Voici comment changer nos documents en majuscules ou en minuscule.

print('@@@@This is lower case@@@@')

with open('students.txt','r')as myFile:

    str1=myFile.read()
    str1.lower()
print(str1.lower())

print('*****This is upper case****')

with open('students.txt','r')as myFile:

    str1=myFile.read()

    str1.upper()

print(str1.upper())

J'aime utiliser une fonction comme celle-ci:

def scrub(abc):
    while abc[-1] is in list(string.punctuation):
        abc=abc[:-1]
    while abc[0] is in list(string.punctuation):
        abc=abc[1:]
    return abc
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top