Necesito eliminar todos los caracteres especiales, signos de puntuación y espacios de una cadena para que solo tenga letras y números.
Necesito eliminar todos los caracteres especiales, signos de puntuación y espacios de una cadena para que solo tenga letras y números.
Respuestas:
Esto se puede hacer sin expresiones regulares:
>>> string = "Special $#! characters spaces 888323"
>>> ''.join(e for e in string if e.isalnum())
'Specialcharactersspaces888323'
Puedes usar str.isalnum
:
S.isalnum() -> bool Return True if all characters in S are alphanumeric and there is at least one character in S, False otherwise.
Si insiste en usar expresiones regulares, otras soluciones funcionarán bien. Sin embargo, tenga en cuenta que si se puede hacer sin usar una expresión regular, esa es la mejor manera de hacerlo.
isalnum()
versiones regex y regex, y la expresión regular es 50-75% más rápida
Aquí hay una expresión regular para que coincida con una cadena de caracteres que no son letras o números:
[^A-Za-z0-9]+
Aquí está el comando Python para hacer una sustitución de expresiones regulares:
re.sub('[^A-Za-z0-9]+', '', mystring)
+
cuantificador para mejorar un poco su eficiencia.)
[^A-Za-z0-9 ]+
Camino más corto:
import re
cleanString = re.sub('\W+','', string )
Si desea espacios entre palabras y números, sustituya '' por ''
r'\W+'
- ligeramente fuera de tema (y muy pedante) pero sugiero un hábito de que todos los patrones de expresiones regulares sean cadenas sin procesar
Después de ver esto, estaba interesado en ampliar las respuestas proporcionadas descubriendo cuál se ejecuta en la menor cantidad de tiempo, así que revisé algunas de las respuestas propuestas con timeit
dos de las cadenas de ejemplo:
string1 = 'Special $#! characters spaces 888323'
string2 = 'how much for the maple syrup? $20.99? That s ricidulous!!!'
'.join(e for e in string if e.isalnum())
string1
- Resultado: 10.7061979771string2
- Resultado: 7.78372597694import re
re.sub('[^A-Za-z0-9]+', '', string)
string1
- Resultado: 7.10785102844string2
- Resultado: 4.12814903259import re
re.sub('\W+','', string)
string1
- Resultado: 3.11899876595string2
- Resultado: 2.78014397621Los resultados anteriores son un producto del resultado más bajo devuelto de un promedio de: repeat(3, 2000000)
El ejemplo 3 puede ser 3 veces más rápido que el ejemplo 1 .
''.join([*filter(str.isalnum, string)])
Creo que solo filter(str.isalnum, string)
funciona
In [20]: filter(str.isalnum, 'string with special chars like !,#$% etcs.')
Out[20]: 'stringwithspecialcharslikeetcs'
En Python3, la filter( )
función devolvería un objeto itertable (en lugar de una cadena a diferencia de lo anterior). Uno tiene que unirse para obtener una cadena de itertable:
''.join(filter(str.isalnum, string))
o para pasar el list
uso de combinación ( no estoy seguro pero puede ser un poco rápido )
''.join([*filter(str.isalnum, string)])
nota: desempaquetado [*args]
válido desde Python> = 3.5
map
, filter
y reduce
vuelve objeto itertable lugar. Todavía en Python3 + preferiré ''.join(filter(str.isalnum, string))
(o aprobar la lista en combinación ''.join([*filter(str.isalnum, string)])
) sobre la respuesta aceptada.
''.join(filter(str.isalnum, string))
es una mejora filter(str.isalnum, string)
, al menos para leer. ¿Es esta realmente la forma Pythreenic (sí, puedes usar eso) para hacer esto?
filter(str.isalnum, string)
no devolver la cadena en Python3 como filter( )
en Python-3 devuelve el iterador en lugar del tipo de argumento a diferencia de Python-2. +
#!/usr/bin/python
import re
strs = "how much for the maple syrup? $20.99? That's ricidulous!!!"
print strs
nstr = re.sub(r'[?|$|.|!]',r'',strs)
print nstr
nestr = re.sub(r'[^a-zA-Z0-9 ]',r'',nstr)
print nestr
puedes agregar más caracteres especiales y eso será reemplazado por "no significa nada, es decir, serán eliminados.
A diferencia de lo que todos los demás usaban regex, trataría de excluir cada personaje que no sea lo que quiero, en lugar de enumerar explícitamente lo que no quiero.
Por ejemplo, si solo quiero caracteres de 'a a z' (mayúsculas y minúsculas) y números, excluiría todo lo demás:
import re
s = re.sub(r"[^a-zA-Z0-9]","",s)
Esto significa "sustituir cada carácter que no sea un número o un carácter en el rango 'a a z' o 'A a Z' con una cadena vacía".
De hecho, si inserta el carácter especial ^
en el primer lugar de su expresión regular, obtendrá la negación.
Consejo adicional: si también necesita minúsculas el resultado, puede hacer que la expresión regular sea aún más rápida y fácil, siempre que no encuentre mayúsculas ahora.
import re
s = re.sub(r"[^a-z0-9]","",s.lower())
Suponiendo que desea usar una expresión regular y desea / necesita un código 2.x compatible con Unicode que esté listo para 2to3:
>>> import re
>>> rx = re.compile(u'[\W_]+', re.UNICODE)
>>> data = u''.join(unichr(i) for i in range(256))
>>> rx.sub(u'', data)
u'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\xaa\xb2 [snip] \xfe\xff'
>>>
El enfoque más genérico es usar las 'categorías' de la tabla unicodedata que clasifica cada carácter. Por ejemplo, el siguiente código filtra solo los caracteres imprimibles según su categoría:
import unicodedata
# strip of crap characters (based on the Unicode database
# categorization:
# http://www.sql-und-xml.de/unicode-database/#kategorien
PRINTABLE = set(('Lu', 'Ll', 'Nd', 'Zs'))
def filter_non_printable(s):
result = []
ws_last = False
for c in s:
c = unicodedata.category(c) in PRINTABLE and c or u'#'
result.append(c)
return u''.join(result).replace(u'#', u' ')
Mire la URL dada arriba para todas las categorías relacionadas. Por supuesto, también puede filtrar por categorías de puntuación.
$
al final de cada línea?
string.punctuation contiene los siguientes caracteres:
'! "# $% & \' () * +, -. / :; <=>? @ [\] ^ _` {|} ~ '
Puede usar las funciones de traducción y conversión para asignar signos de puntuación a valores vacíos (reemplazar)
import string
'This, is. A test!'.translate(str.maketrans('', '', string.punctuation))
Salida:
'This is A test'
Usa traductor:
import string
def clean(instr):
return instr.translate(None, string.punctuation + ' ')
Advertencia: solo funciona en cadenas ASCII.
TypeError: translate() takes exactly one argument (2 given)
con py3.4
import re
my_string = """Strings are amongst the most popular data types in Python. We can create the strings by enclosing characters in quotes. Python treats single quotes the
igual que las comillas dobles "" "
# if we need to count the word python that ends with or without ',' or '.' at end
count = 0
for i in text:
if i.endswith("."):
text[count] = re.sub("^([a-z]+)(.)?$", r"\1", i)
count += 1
print("The count of Python : ", text.count("python"))
import re
abc = "askhnl#$%askdjalsdk"
ddd = abc.replace("#$%","")
print (ddd)
y verás tu resultado como
'askhnlaskdjalsdk
re
pero nunca lo usaste. Sus replace
criterios solo funcionan para esta cadena específica. ¿Qué pasa si tu cuerda es abc = "askhnl#$%!askdjalsdk"
? No creo que funcione en otra cosa que no sea el #$%
patrón. Podría querer modificarlo
Eliminar signos de puntuación, números y caracteres especiales
Ejemplo:
Código
combi['tidy_tweet'] = combi['tidy_tweet'].str.replace("[^a-zA-Z#]", " ")
Gracias :)
Para otros idiomas como el alemán, español, danés, francés, etc., que contienen caracteres especiales (como el alemán "Umlaute", como ü
, ä
, ö
) simplemente añadir estos a la cadena de búsqueda de expresiones regulares:
Ejemplo para alemán:
re.sub('[^A-ZÜÖÄa-z0-9]+', '', mystring)