2009-08-08 9 views

Respuesta

153
>>> import re 
>>> re.sub("[^0-9]", "", "sdkjh987978asd098as0980a98sd") 
'987978098098098' 
+61

que podría ser re.sub (r "\ D", "", "sdkjh987978asd098as0980a98sd") – newacct

59

No estoy seguro si esta es la manera más eficiente, pero:

>>> ''.join(c for c in "abc123def456" if c.isdigit()) 
'123456' 

La parte ''.join significa combinar todos los caracteres resultantes juntos sin ningún carácter en el medio. Luego, el resto es una lista de comprensión, donde (como probablemente puedas adivinar) solo tomamos las partes de la cadena que coinciden con la condición isdigit.

+1

Eso hace lo contrario. Creo que te refieres a "no c.isdigit()" –

+7

Eliminar todo lo no numérico == mantener solo numérico. –

+7

Me gusta que este enfoque no requiera el pull in re, para esta sencilla función. – triunenature

4

más rápido enfoque, si necesita realizar más de sólo una o dos de estas operaciones de eliminación (o incluso sólo uno, sino en una cadena muy larga! -), es confiar en el método de cadenas translate, a pesar de que necesita un poco de preparación:

>>> import string 
>>> allchars = ''.join(chr(i) for i in xrange(256)) 
>>> identity = string.maketrans('', '') 
>>> nondigits = allchars.translate(identity, string.digits) 
>>> s = 'abc123def456' 
>>> s.translate(identity, nondigits) 
'123456' 

El método translate es diferente, y quizás un poco más sencillo más fácil de usar, en cadenas Unicode de lo que es en cadenas de bytes, por cierto:

>>> unondig = dict.fromkeys(xrange(65536)) 
>>> for x in string.digits: del unondig[ord(x)] 
... 
>>> s = u'abc123def456' 
>>> s.translate(unondig) 
u'123456' 

Puede usar una clase de mapeo en lugar de una dicción real, especialmente si su cadena Unicode puede contener caracteres con valores ord muy altos (eso haría que el dic sea excesivamente grande ;-). Por ejemplo:

>>> class keeponly(object): 
... def __init__(self, keep): 
...  self.keep = set(ord(c) for c in keep) 
... def __getitem__(self, key): 
...  if key in self.keep: 
...  return key 
...  return None 
... 
>>> s.translate(keeponly(string.digits)) 
u'123456' 
>>> 
+1

(1) No codificar números mágicos; s/65536/sys.maxunicode/(2) El dict es incondicionalmente "excesivamente grande" porque la entrada "potencialmente" puede contener entradas '(sys.maxunicode - number_of_non_numeric_chars)'. (3) considere si string.digits puede no ser suficiente para abrir el módulo unicodedata (4) considere re.sub (r '(? U) \ D +', u '', texto) para simplificar y potencializar velocidad. –

12

Esto debería funcionar para cuerdas y objetos Unicode:

# python <3.0 
def only_numerics(seq): 
    return filter(type(seq).isdigit, seq) 

# python ≥3.0 
def only_numerics(seq): 
    seq_type= type(seq) 
    return seq_type().join(filter(seq_type.isdigit, seq)) 
+0

y solo en python 2.x – SilentGhost

+1

Gracias por el recordatorio, SilentGhost. – tzot

+1

Tiene una barra diagonal inversa, pero SO no me deja arreglarlo. –

4

sólo para añadir otra opción a la mezcla, hay varias constantes útiles dentro del módulo string. Si bien es más útil en otros casos, se pueden usar aquí.

>>> from string import digits 
>>> ''.join(c for c in "abc123def456" if c in digits) 
'123456' 

Hay varias constantes en el módulo, incluyendo:

  • ascii_letters (ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz)
  • hexdigits (abcdefABCDEF)

Si está utilizando estas constantes en gran medida, lo que puede Valga la pena encubrirlos a frozenset. Eso habilita O (1) búsquedas, en lugar de O (n), donde n es la longitud de la constante para las cadenas originales.

>>> digits = frozenset(digits) 
>>> ''.join(c for c in "abc123def456" if c in digits) 
'123456' 
+0

'' .join (c para c en "abc123def456" si c.isdigit()) funciona en mi python 3.4 –

-6
user = (input): 
print ("hello") 
Cuestiones relacionadas