Risposte:
>>> import re
>>> re.sub("[^0-9]", "", "sdkjh987978asd098as0980a98sd")
'987978098098098'
Non sono sicuro se questo è il modo più efficiente, ma:
>>> ''.join(c for c in "abc123def456" if c.isdigit())
'123456'
La ''.join
parte significa combinare tutti i personaggi risultanti insieme senza alcun carattere in mezzo. Quindi il resto è una comprensione dell'elenco, in cui (come probabilmente puoi immaginare) prendiamo solo le parti della stringa che corrispondono alla condizione isdigit
.
Questo dovrebbe funzionare sia per le stringhe che per gli oggetti unicode in Python2 e per entrambe le stringhe e i byte in Python3:
# 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))
Solo per aggiungere un'altra opzione al mix, ci sono diverse costanti utili all'interno del string
modulo. Sebbene più utili in altri casi, possono essere utilizzati qui.
>>> from string import digits
>>> ''.join(c for c in "abc123def456" if c in digits)
'123456'
Esistono diverse costanti nel modulo, tra cui:
ascii_letters
(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz)hexdigits
(0123456789abcdefABCDEF)Se stai usando queste costanti pesantemente, può essere utile convertirle in a frozenset
. Ciò abilita le ricerche O (1), anziché O (n), dove n è la lunghezza della costante per le stringhe originali.
>>> digits = frozenset(digits)
>>> ''.join(c for c in "abc123def456" if c in digits)
'123456'
L'approccio più rapido, se è necessario eseguire più di una o due di tali operazioni di rimozione (o anche solo una, ma su una stringa molto lunga! -), è fare affidamento sul translate
metodo delle stringhe, anche se necessita di alcune prep:
>>> 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'
Il translate
metodo è diverso, e forse un po 'più semplice da usare, sulle stringhe Unicode rispetto alle stringhe di byte, a proposito:
>>> unondig = dict.fromkeys(xrange(65536))
>>> for x in string.digits: del unondig[ord(x)]
...
>>> s = u'abc123def456'
>>> s.translate(unondig)
u'123456'
Potresti voler usare una classe di mappatura piuttosto che un vero dict, specialmente se la tua stringa Unicode potrebbe potenzialmente contenere caratteri con valori ord molto alti (ciò renderebbe il dict eccessivamente grande ;-). Per esempio:
>>> 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'
>>>
(sys.maxunicode - number_of_non_numeric_chars)
voci. (3) considera se string.digits potrebbe non essere sufficiente portando alla necessità di aprire il modulo unicodedata (4) considera re.sub (r '(? U) \ D +', u '', text) per semplicità e potenziale velocità.
Molte risposte giuste, ma nel caso tu lo voglia in un float, direttamente, senza usare regex:
x= '$123.45M'
float(''.join(c for c in x if (c.isdigit() or c =='.'))
123.45
È possibile modificare il punto per una virgola in base alle proprie esigenze.
cambia per questo se sai che il tuo numero è un numero intero
x='$1123'
int(''.join(c for c in x if c.isdigit())
1123