Eliminar caracteres específicos de una cadena en Python

Resuelto Matt Phillips asked hace 14 años • 27 respuestas

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.

Matt Phillips avatar Oct 15 '10 10:10 Matt Phillips
Aceptado

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 lineque 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 lineque 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 translatemétodo de una cadena Unicode, no puede pasar el segundo parámetro que usamos anteriormente. Tampoco puedes pasarlo Nonecomo 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, Nonepara 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.fromkeysy mapse 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.maketransse utiliza para crear una tabla de traducción , que es solo una cadena que contiene los caracteres con valores ordinales del 0 al 255.

intuited avatar Oct 15 '2010 03:10 intuited

¿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"
gsbabil avatar Oct 15 '2010 12:10 gsbabil

Con re.subexpresión regular

Desde Python 3.5, la sustitución mediante expresiones regulares re.subestuvo 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 subrepresenta sustitución, en este caso con la cadena vacía ''.

Serge Stroobandt avatar Sep 25 '2017 21:09 Serge Stroobandt

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.

mgold avatar Dec 14 '2011 18:12 mgold