Ich habe eine Reihe von Zeichenfolgen ähnlich Current Level: 13.4 db.
und ich möchte nur die Gleitkommazahl extrahieren. Ich sage schwebend und nicht dezimal, da es manchmal ganz ist. Kann RegEx dies tun oder gibt es einen besseren Weg?
Wenn Ihr Float immer in Dezimalschreibweise ausgedrückt wird, ist das ungefähr so
>>> import re
>>> re.findall("\d+\.\d+", "Current Level: 13.4 db.")
['13.4']
kann ausreichen.
Eine robustere Version wäre:
>>> re.findall(r"[-+]?\d*\.\d+|\d+", "Current Level: -13.2 db or 14.2 or 3")
['-13.2', '14.2', '3']
Wenn Sie eine Benutzereingabe validieren möchten, können Sie alternativ auch direkt darauf zugreifen, um nach einem Float zu suchen:
user_input = "Current Level: 1e100 db"
for token in user_input.split():
try:
# if this succeeds, you have your (first) float
print float(token), "is a float"
except ValueError:
print token, "is something else"
# => Would print ...
#
# Current is something else
# Level: is something else
# 1e+100 is a float
# db is something else
Möglicherweise möchten Sie etwas Ähnliches ausprobieren, das alle Grundlagen abdeckt, einschließlich des Verzichts auf Leerzeichen nach der Nummer:
>>> import re
>>> numeric_const_pattern = r"""
... [-+]? # optional sign
... (?:
... (?: \d* \. \d+ ) # .1 .12 .123 etc 9.1 etc 98.1 etc
... |
... (?: \d+ \.? ) # 1. 12. 123. etc 1 12 123 etc
... )
... # followed by optional exponent part if desired
... (?: [Ee] [+-]? \d+ ) ?
... """
>>> rx = re.compile(numeric_const_pattern, re.VERBOSE)
>>> rx.findall(".1 .12 9.1 98.1 1. 12. 1 12")
['.1', '.12', '9.1', '98.1', '1.', '12.', '1', '12']
>>> rx.findall("-1 +1 2e9 +2E+09 -2e-9")
['-1', '+1', '2e9', '+2E+09', '-2e-9']
>>> rx.findall("current level: -2.03e+99db")
['-2.03e+99']
>>>
Zum einfachen Kopieren und Einfügen:
numeric_const_pattern = '[-+]? (?: (?: \d* \. \d+ ) | (?: \d+ \.? ) )(?: [Ee] [+-]? \d+ ) ?'
rx = re.compile(numeric_const_pattern, re.VERBOSE)
rx.findall("Some example: Jr. it. was .23 between 2.3 and 42.31 seconds")
Python docs hat eine Antwort, die +/- und Exponentennotation abdeckt
scanf() Token Regular Expression
%e, %E, %f, %g [-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?
%i [-+]?(0[xX][\dA-Fa-f]+|0[0-7]*|\d+)
Dieser reguläre Ausdruck unterstützt keine internationalen Formate, bei denen ein Komma als Trennzeichen zwischen dem ganzen und dem gebrochenen Teil verwendet wird (3,14159). In diesem Fall ersetzen Sie alle \.
mit [.,]
im obigen Float-Regex.
Regular Expression
International float [-+]?(\d+([.,]\d*)?|[.,]\d+)([eE][-+]?\d+)?
re.findall(r"[-+]?\d*\.\d+|\d+", "Current Level: -13.2 db or 14.2 or 3")
wie oben beschrieben, funktioniert wirklich gut! Ein Vorschlag jedoch:
re.findall(r"[-+]?\d*\.\d+|[-+]?\d+", "Current Level: -13.2 db or 14.2 or 3 or -3")
gibt auch negative int Werte zurück (wie -3 am Ende dieser Zeichenkette)
Sie können den folgenden regulären Ausdruck verwenden, um Ganzzahl- und Gleitkommawerte aus einer Zeichenfolge abzurufen:
re.findall(r'[\d\.\d]+', 'hello -34 42 +34.478m 88 cricket -44.3')
['34', '42', '34.478', '88', '44.3']
Danke Rex
Ich denke, dass Sie interessante Dinge in der folgenden Antwort von mir finden werden, die ich für eine vorhergehende ähnliche Frage gemacht habe:
https://stackoverflow.com/q/5929469/551449
In dieser Antwort habe ich ein Muster vorgeschlagen, mit dem ein Regex jede Art von Zahl erfassen kann, und da ich nichts anderes hinzuzufügen habe, denke ich, dass es ziemlich vollständig ist
Ein weiterer Ansatz, der besser lesbar sein kann, ist die einfache Typkonvertierung. Ich habe eine Ersatzfunktion hinzugefügt, um Fälle abzudecken, in denen Personen europäische Dezimalstellen eingeben können:
>>> for possibility in "Current Level: -13.2 db or 14,2 or 3".split():
... try:
... str(float(possibility.replace(',', '.')))
... except ValueError:
... pass
'-13.2'
'14.2'
'3.0'
Dies hat jedoch auch Nachteile. Wenn jemand "1,000" eingibt, wird dies in 1 konvertiert. Außerdem wird davon ausgegangen, dass die Leute Leerzeichen zwischen den Wörtern eingeben. Dies ist bei anderen Sprachen wie Chinesisch nicht der Fall.