Odpowiedzi:
>>> import re
>>> re.sub("[^0-9]", "", "sdkjh987978asd098as0980a98sd")
'987978098098098'
Nie jestem pewien, czy jest to najbardziej efektywny sposób, ale:
>>> ''.join(c for c in "abc123def456" if c.isdigit())
'123456'
Te ''.join
środki część połączyć wszystkie wynikowe znaki razem bez żadnych znaków pomiędzy. Reszta jest listą, w której (jak można się domyślić) bierzemy tylko te części ciągu, które pasują do warunku isdigit
.
Powinno to zadziałać zarówno dla ciągów znaków, jak i obiektów Unicode w Python2 oraz dla ciągów i bajtów w 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))
Aby dodać kolejną opcję do miksu, w string
module jest kilka przydatnych stałych . Chociaż są bardziej przydatne w innych przypadkach, można ich tutaj użyć.
>>> from string import digits
>>> ''.join(c for c in "abc123def456" if c in digits)
'123456'
W module jest kilka stałych, w tym:
ascii_letters
(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ)hexdigits
(0123456789abcdefABCDEF)Jeśli intensywnie używasz tych stałych, warto zamienić je na plik frozenset
. To umożliwia wyszukiwanie O (1) zamiast O (n), gdzie n jest długością stałej dla oryginalnych ciągów.
>>> digits = frozenset(digits)
>>> ''.join(c for c in "abc123def456" if c in digits)
'123456'
Najszybszym podejściem, jeśli musisz wykonać więcej niż jedną lub dwie takie operacje usuwania (lub nawet jedną, ale na bardzo długim łańcuchu! -), jest poleganie na translate
metodzie ciągów, nawet jeśli wymaga to przygotowania:
>>> 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'
translate
Metoda jest inna i może odrobinę prostsze prostsze w użyciu, na Unicode, niż jest na ciągi bajtów, btw:
>>> unondig = dict.fromkeys(xrange(65536))
>>> for x in string.digits: del unondig[ord(x)]
...
>>> s = u'abc123def456'
>>> s.translate(unondig)
u'123456'
Możesz chcieć użyć klasy mapowania zamiast faktycznego dyktu, zwłaszcza jeśli twój łańcuch Unicode może potencjalnie zawierać znaki o bardzo wysokich wartościach ord (które spowodowałyby, że dykt byłby zbyt duży ;-). Na przykład:
>>> 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)
wpisy. (3) rozważ, czy string.digits może być niewystarczające, co prowadzi do konieczności złamania modułu unicodedata (4) rozważ re.sub (r '(? U) \ D +', u '', text) dla uproszczenia i potencjału prędkość.
Wiele poprawnych odpowiedzi, ale na wypadek, gdybyś chciał, aby to było zmiennoprzecinkowe, bezpośrednio, bez użycia wyrażenia regularnego:
x= '$123.45M'
float(''.join(c for c in x if (c.isdigit() or c =='.'))
123,45
Możesz zmienić punkt przecinka w zależności od potrzeb.
zmień to, jeśli wiesz, że Twój numer jest liczbą całkowitą
x='$1123'
int(''.join(c for c in x if c.isdigit())
1123