Necesito reemplazar caracteres no numéricos de una cadena.Reemplazar caracteres no numéricos
Por ejemplo, "8-4545-225-144" debe ser "84545225144"; "$ 334fdf890 == -" debe ser "334890".
¿Cómo puedo hacer esto?
Necesito reemplazar caracteres no numéricos de una cadena.Reemplazar caracteres no numéricos
Por ejemplo, "8-4545-225-144" debe ser "84545225144"; "$ 334fdf890 == -" debe ser "334890".
¿Cómo puedo hacer esto?
''.join(c for c in S if c.isdigit())
Es posible con expresiones regulares.
import re
...
return re.sub(r'\D', '', theString)
Aunque un poco más complicado de configurar, utilizando el método translate()
cadena a eliminar los caracteres que se muestran a continuación pueden tanto como 4-6 veces más rápido que el uso de join()
o re.sub()
según la duración pruebas que realizamos - así que si es algo que se hace muchas veces, quizás quieras considerar usarlo.
nonnumerics = ''.join(c for c in ''.join(chr(i) for i in range(256)) if not c.isdigit())
astring = '123-$ab #6789'
print astring.translate(None, nonnumerics)
# 1236789
El método str.translate se prefiere sobre string.translate. –
@Roger Pate, buen punto, los viejos hábitos son difíciles de romper ... He actualizado el código en mi respuesta en consecuencia.Gracias por señalarlo y permitirme mejorar el código de muestra. – martineau
prefiero expresiones regulares, así que aquí está una manera si se quiere
import re
myStr = '$334fdf890==-'
digts = re.sub('[^0-9]','',myStr)
Esto debe reemplazar todas las ocurrencias no numéricos con '' es decir, sin nada. Tan variable digts debería ser el momento '334890'
Vamos a la join
y las versiones re
:
In [3]: import re
In [4]: def withRe(theString): return re.sub('\D', '', theString)
...:
In [5]:
In [6]: def withJoin(S): return ''.join(c for c in S if c.isdigit())
...:
In [11]: s = "8-4545-225-144"
In [12]: %timeit withJoin(s)
100000 loops, best of 3: 6.89 us per loop
In [13]: %timeit withRe(s)
100000 loops, best of 3: 4.77 us per loop
La versión join
es mucho más agradable, en comparación con el re
uno, pero por desgracia es un 50% más lento. Entonces, si el rendimiento es un problema, podría ser necesario sacrificar la elegancia.
EDITAR
In [16]: def withFilter(s): return filter(str.isdigit, s)
....:
In [19]: %timeit withFilter(s)
100000 loops, best of 3: 2.75 us per loop
Parece que filter
es el ganador rendimiento y facilidad de lectura
filter(str.isdigit, s)
es más rápido y la OMI más clara que cualquier otra cosa que aparece aquí.
También lanzará un TypeError si s es de tipo Unicode. Dependiendo de la definición de "dígitos" que desee, esto puede ser más o menos útil que la alternativa filter(type(s).isdigit, s)
, un poco más lenta pero aún más rápida que las versiones de re y comprensión para mí.
Editar: Aunque si usted es un lechón pobre pegado con Python 3, que tendrá que utilizar "".join(filter(str.isdigit, s))
que te pone firmemente en el ámbito de lo que es equivalente mal desempeño. Tal progreso.
Odio cuando las personas cierran una lista de comprensión cuando la expresión de un generador es la opción correcta. Usted, señor, gana un internet (y un voto positivo). – delnan
+1 para solución no regex. odio cuando las personas usan expresiones regulares para todo, algunos objetivos se adaptan mejor con la solución no regex – killown
@killown: Personalmente encuentro la opción de expresiones regulares más legible. Tal vez es porque he trabajado tanto con expresiones regulares, pero mirando el código de @ KennyTM puedo ver de inmediato lo que hace; esto me lleva un segundo entender. –