Pregunta

Parece que debería haber una forma más simple que:

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

¿Hay?

¿Fue útil?

Solución

Desde una perspectiva de eficiencia, no vas a vencer

s.translate(None, string.punctuation)

Para versiones superiores de Python use el siguiente código:

s.translate(str.maketrans('', '', string.punctuation))

Realiza operaciones de cadena sin formato en C con una tabla de búsqueda; no hay mucho que supere eso, sino escribir su propio código C.

Si la velocidad no es una preocupación, otra opción es:

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

Esto es más rápido que reemplazarlo con cada char, pero no funcionará tan bien como los enfoques de Python no puros como regexes o string.translate, como puede ver en los siguientes tiempos. Para este tipo de problema, vale la pena hacerlo al nivel más bajo posible.

Código de tiempo:

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)

Esto da los siguientes resultados:

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

Otros consejos

Las expresiones regulares son bastante simples, si las conoce.

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

En el código anterior, estamos sustituyendo (re.sub) todos los NO [caracteres alfanuméricos (\ w) y espacios (\ s)] con una cadena vacía.
Por lo tanto y? la puntuación no estará presente en la variable 's' después de ejecutar s variable a través de la expresión regular.

Para la conveniencia del uso, resumo la nota de puntuación de rayas de una cadena en Python 2 y Python 3. Consulte otras respuestas para obtener una descripción detallada.


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)

Usualmente uso algo como esto:

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

string.punctuation es ASCII solamente ! Una forma más correcta (pero también mucho más lenta) es usar el módulo 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

No necesariamente más simple, pero de una manera diferente, si está más familiarizado con la familia re.

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

Para los valores str o Python 2 unicode de Python 3, str.translate () solo toma un diccionario; los puntos de código (enteros) se buscan en ese mapeo y todo lo mapeado a None se elimina.

Para eliminar la puntuación (¿alguna?) entonces, use:

import string

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

La clase dict.fromkeys () El método hace que sea trivial crear la asignación, estableciendo todos los valores en None en función de la secuencia de teclas.

Para eliminar la puntuación all , no solo la puntuación ASCII, la tabla debe ser un poco más grande; ver J.F. La respuesta de Sebastián (versión 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 pierde un montón de signos de puntuación que se usan comúnmente en el mundo real. ¿Qué tal una solución que funciona para la puntuación no 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()

Personalmente, creo que esta es la mejor manera de eliminar la puntuación de una cadena en Python porque:

  • Elimina todos los signos de puntuación Unicode
  • Es fácilmente modificable, p. puede eliminar el \ {S} si desea eliminar la puntuación, pero mantenga símbolos como $ .
  • Puede ser realmente específico sobre lo que desea conservar y lo que desea eliminar, por ejemplo, \ {Pd} solo eliminará guiones.
  • Esta expresión regular también normaliza los espacios en blanco. Asigna pestañas, retornos de carro y otras rarezas a espacios agradables y únicos.

Esto utiliza propiedades de caracteres Unicode, que puede leer más sobre Wikipedia .

Esta podría no ser la mejor solución, sin embargo, así es como lo hice.

import string
f = lambda x: ''.join([i for i in x if i not in string.punctuation])

Aquí hay una función que escribí. No es muy eficiente, pero es simple y puede agregar o eliminar cualquier puntuación que desee:

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

Aquí hay una línea para 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}))

Todavía no he visto esta respuesta. Solo usa una expresión regular; elimina todos los caracteres además de los caracteres de palabra ( \ w ) y los caracteres numéricos ( \ d ), seguidos de un carácter de espacio en blanco ( \ s ):

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

Aquí hay una solución sin expresiones regulares.

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
  • Reemplaza los signos de puntuación con espacios
  • Reemplazar múltiples espacios entre palabras con un solo espacio
  • Elimine los espacios finales, si hay alguno con tira ()

Solo como una actualización, reescribí el ejemplo @Brian en Python 3 e hice cambios para mover el paso de compilación de expresiones regulares dentro de la función. Mi pensamiento aquí era cronometrar cada paso necesario para que la función funcionara. Tal vez está utilizando la informática distribuida y no puede tener un objeto regex compartido entre sus trabajadores y necesita tener un paso re.compile en cada trabajador. Además, tenía curiosidad por programar dos implementaciones diferentes de maketrans para Python 3

table = str.maketrans({key: None for key in string.punctuation})

vs

table = str.maketrans('', '', string.punctuation)

Además, agregué otro método para usar set, donde aprovecho la función de intersección para reducir el número de iteraciones.

Este es el código completo:

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

Estos son mis resultados:

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)

Un one-liner puede ser útil en casos no muy estrictos:

''.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 ("____________")

Eliminar palabras de detención del archivo de texto usando 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')

Así es como cambiar nuestros documentos a mayúsculas o minúsculas.

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

Me gusta usar una función como esta:

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top