Frage

Diese Frage bereits eine Antwort hier:

ich eine Reihe von Strings ähnlich wie Current Level: 13.4 db. haben, und ich möchte nur die Gleitkommazahl extrahieren. Ich sage schwimmend und nicht dezimal, wie es manchmal ganz ist. Can RegEx dies tun, oder gibt es einen besseren Weg?

War es hilfreich?

Lösung

Wenn Ihr Schwimmer in Dezimalschreibweise so etwas wie

immer ausgedrückt
>>> import re
>>> re.findall("\d+\.\d+", "Current Level: 13.4 db.")
['13.4']

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 auf Benutzereingabe prüfen möchten, können Sie alternativ auch für einen Schwimmer überprüfen, indem es verstärkt direkt an:

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

Andere Tipps

Sie können mögen, so etwas versuchen, die alle Basen umfassen, einschließlich dem nicht nach der Anzahl an Leerzeichen setzen:

>>> 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']
>>>

Für eine einfache Kopie-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, dass Abdeckungen +/- und Exponenten-Darstellung

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 nicht internationale Formate unterstützen, in denen ein Komma als Trennzeichen zwischen dem Ganzen und Bruchteil verwendet wird (3,14159). In diesem Fall ersetzt all \. mit [.,] in der obigen Schwimmer 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 aber:

re.findall(r"[-+]?\d*\.?\d+|[-+]?\d+", "Current Level: -13.2 db or 14.2 or 3 or -3")

wird auch negative int Werte zurück (wie -3 am Ende dieser Zeichenfolge)

Sie können die folgende regex verwenden integer zu erhalten und Floating-Werte aus einer Zeichenfolge:

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, dass ich für eine frühere ähnliche Frage habe:

https://stackoverflow.com/q/5929469/551449

In dieser Antwort habe ich vorgeschlagen, ein Muster, das ein regulärer Ausdruck, jede Art von Zahl fangen können und da ich nichts anderes, um es hinzuzufügen, ich denke, es ist ziemlich vollständig ist

Ein weiterer Ansatz, der besser lesbar sein kann, ist einfach Typumwandlung. Ich habe eine Ersatzfunktion zu Abdeckung Instanzen hinzugefügt, wo die Menschen 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 auch Nachteile jedoch. Wenn jemand Typen in „1000“, wird dies auch auf 1 umgewandelt werden, nimmt es, dass die Menschen mit Leerzeichen zwischen den Wörtern werden die Eingabe. Dies ist nicht der Fall mit anderen Sprachen, wie Chinesisch.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top