Antworten:
>>> import re
>>> re.sub("[^0-9]", "", "sdkjh987978asd098as0980a98sd")
'987978098098098'
Ich bin mir nicht sicher, ob dies der effizienteste Weg ist, aber:
>>> ''.join(c for c in "abc123def456" if c.isdigit())
'123456'
Der ''.join
Teil bedeutet, alle resultierenden Zeichen ohne dazwischen liegende Zeichen miteinander zu kombinieren. Dann ist der Rest ein Listenverständnis, bei dem wir (wie Sie wahrscheinlich erraten können) nur die Teile der Zeichenfolge nehmen, die der Bedingung entsprechen isdigit
.
Dies sollte sowohl für Zeichenfolgen als auch für Unicode-Objekte in Python2 und für Zeichenfolgen und Bytes in Python3 funktionieren:
# 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))
Um der Mischung eine weitere Option hinzuzufügen, gibt es im string
Modul mehrere nützliche Konstanten . In anderen Fällen sind sie zwar nützlicher, können aber hier verwendet werden.
>>> from string import digits
>>> ''.join(c for c in "abc123def456" if c in digits)
'123456'
Das Modul enthält mehrere Konstanten, darunter:
ascii_letters
(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ)hexdigits
(0123456789abcdefABCDEF)Wenn Sie diese Konstanten häufig verwenden, kann es sich lohnen, sie in a umzuwandeln frozenset
. Dies ermöglicht O (1) -Suchen anstelle von O (n), wobei n die Länge der Konstante für die ursprünglichen Zeichenfolgen ist.
>>> digits = frozenset(digits)
>>> ''.join(c for c in "abc123def456" if c in digits)
'123456'
Der schnellste Ansatz, wenn Sie mehr als nur ein oder zwei solcher Entfernungsvorgänge ausführen müssen (oder sogar nur einen, aber an einer sehr langen Zeichenfolge! -), besteht darin, sich auf die translate
Methode der Zeichenfolgen zu verlassen, obwohl einige Vorbereitungen erforderlich sind:
>>> 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'
Die translate
Methode ist bei Unicode-Zeichenfolgen anders und möglicherweise etwas einfacher zu verwenden als bei Byte-Zeichenfolgen, übrigens:
>>> unondig = dict.fromkeys(xrange(65536))
>>> for x in string.digits: del unondig[ord(x)]
...
>>> s = u'abc123def456'
>>> s.translate(unondig)
u'123456'
Möglicherweise möchten Sie eine Zuordnungsklasse anstelle eines tatsächlichen Diktats verwenden, insbesondere wenn Ihre Unicode-Zeichenfolge möglicherweise Zeichen mit sehr hohen Ordnungswerten enthält (dies würde das Diktat übermäßig groß machen ;-). Beispielsweise:
>>> 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)
Einträge enthalten kann . (3) Überlegen Sie, ob string.digits möglicherweise nicht ausreichen, was dazu führt, dass das Unicodedata-Modul aufgebrochen werden muss. (4) Überlegen Sie der Einfachheit und dem Potenzial nach re (r '(? U) \ D +', u '', Text) Geschwindigkeit.
Viele richtige Antworten, aber falls Sie es direkt in einem Float möchten, ohne Regex zu verwenden:
x= '$123.45M'
float(''.join(c for c in x if (c.isdigit() or c =='.'))
123,45
Sie können den Punkt für ein Komma je nach Ihren Anforderungen ändern.
Ändern Sie dies, wenn Sie wissen, dass Ihre Nummer eine Ganzzahl ist
x='$1123'
int(''.join(c for c in x if c.isdigit())
1123