Eliminar caracteres específicos de una cadena en Python
Estoy intentando eliminar caracteres específicos de una cadena usando Python. Este es el código que estoy usando ahora mismo. Desafortunadamente, parece que no le hace nada a la cuerda.
for char in line:
if char in " ?.!/;:":
line.replace(char,'')
¿Cómo hago esto correctamente?
Consulte ¿Por qué llamar a un método de cadena (como .replace o .strip) no modifica (muta) la cadena? para la pregunta de depuración específica sobre qué está mal en este enfoque. Las respuestas aquí se centran principalmente en cómo resolver el problema.
Las cadenas en Python son inmutables (no se pueden cambiar). Debido a esto, el efecto de line.replace(...)
es simplemente crear una nueva cadena, en lugar de cambiar la anterior. Debe volver a vincularlo (asignarlo) para line
que esa variable tome el nuevo valor, sin esos caracteres.
Además, la forma en que lo hagas será relativamente lenta. También es probable que resulte un poco confuso para los pitonistas experimentados, quienes verán una estructura doblemente anidada y pensarán por un momento que está sucediendo algo más complicado.
A partir de Python 2.6 y versiones más recientes de Python 2.x *, puede usar en su lugar str.translate
( consulte la respuesta de Python 3 a continuación ):
line = line.translate(None, '!@#$')
o reemplazo de expresión regular conre.sub
import re
line = re.sub('[!@#$]', '', line)
Los caracteres encerrados entre corchetes constituyen una clase de carácter . Cualquier carácter line
que esté en esa clase se reemplaza con el segundo parámetro para sub
: una cadena vacía.
Respuesta de Python 3
En Python 3, las cadenas son Unicode. Tendrás que traducir un poco diferente. kevpie menciona esto en un comentario sobre una de las respuestas y está anotado en la documentación destr.translate
.
Al llamar al translate
método de una cadena Unicode, no puede pasar el segundo parámetro que usamos anteriormente. Tampoco puedes pasarlo None
como primer parámetro. En su lugar, pasa una tabla de traducción (normalmente un diccionario) como único parámetro. Esta tabla asigna los valores ordinales de los caracteres (es decir, el resultado de invocarlos ord
) a los valores ordinales de los caracteres que deberían reemplazarlos o, útil para nosotros, None
para indicar que deben eliminarse.
Entonces, para hacer el baile anterior con una cadena Unicode llamarías algo como
translation_table = dict.fromkeys(map(ord, '!@#$'), None)
unicode_line = unicode_line.translate(translation_table)
Aquí dict.fromkeys
y map
se utilizan para generar de manera sucinta un diccionario que contiene
{ord('!'): None, ord('@'): None, ...}
Aún más simple, como dice otra respuesta , cree la tabla de traducción en su lugar:
unicode_line = unicode_line.translate({ord(c): None for c in '!@#$'})
O, como lo mencionó Joseph Lee , cree la misma tabla de traducción con str.maketrans
:
unicode_line = unicode_line.translate(str.maketrans('', '', '!@#$'))
* para compatibilidad con Pythons anteriores, puede crear una tabla de traducción "nula" para pasar en lugar de None
:
import string
line = line.translate(string.maketrans('', ''), '!@#$')
Aquí string.maketrans
se utiliza para crear una tabla de traducción , que es solo una cadena que contiene los caracteres con valores ordinales del 0 al 255.
¿Me estoy perdiendo el punto aquí, o es solo lo siguiente?
string = "ab1cd1ef"
string = string.replace("1", "")
print(string)
# result: "abcdef"
Ponlo en un bucle:
a = "a!b@c#d$"
b = "!@#$"
for char in b:
a = a.replace(char, "")
print(a)
# result: "abcd"
Con re.sub
expresión regular
Desde Python 3.5, la sustitución mediante expresiones regulares re.sub
estuvo disponible:
import re
re.sub('\ |\?|\.|\!|\/|\;|\:', '', line)
Ejemplo
import re
line = 'Q: Do I write ;/.??? No!!!'
re.sub('\ |\?|\.|\!|\/|\;|\:', '', line)
'QDoIwriteNo'
Explicación
En las expresiones regulares (regex), |
es un OR lógico y \
escapa espacios y caracteres especiales que podrían ser comandos de expresiones regulares reales. Mientras que sub
representa sustitución, en este caso con la cadena vacía ''
.
El autor de la pregunta casi lo entendió. Como la mayoría de las cosas en Python, la respuesta es más simple de lo que piensas.
>>> line = "H E?.LL!/;O:: "
>>> for char in ' ?.!/;:':
... line = line.replace(char,'')
...
>>> print line
HELLO
No tienes que hacer el bucle anidado if/for, pero SÍ necesitas verificar cada carácter individualmente.