716 Stimmen

Wie extrahiert man Zahlen aus einer Zeichenkette in Python?

Ich möchte alle in einer Zeichenkette enthaltenen Zahlen extrahieren. Was ist für diesen Zweck besser geeignet, reguläre Ausdrücke oder die isdigit() Methode?

line = "hello 12 hi 89"

Ergebnis:

[12, 89]

4 Stimmen

Leider waren die Beispiel-Eingabedaten so simpel, dass sie zu naiven Lösungen einluden. Übliche Fälle sollten Eingabezeichenfolgen mit interessanteren Zeichen neben den Ziffern behandeln. Eine etwas anspruchsvollere Eingabe: '''gimme digits from "12", 34, '56', -789.'''

42voto

jameshollisandrew Punkte 943

Um verschiedene Muster zu erfassen, ist es hilfreich, verschiedene Muster abzufragen.

Richten Sie alle Muster ein, die für verschiedene Zahlenmuster von Interesse sind:

(mit Kommas) 12.300 oder 12.300,00

'[ \d ]+[., \d ]+'

(findet Schwimmer) 0,123 oder .123

'[ \d ]*[.][ \d ]+'

(findet ganze Zahlen) 123

'[ \d ]+'

Kombinieren mit Pipe ( | ) zu einem Muster mit mehreren oder Konditionalitäten .

(Hinweis: Setzen Sie komplexe Muster zuerst ein, sonst geben einfache Muster Teile des komplexen Catches zurück, anstatt dass der komplexe Catch den gesamten Catch zurückgibt).

p = '[\d]+[.,\d]+|[\d]*[.][\d]+|[\d]+'

Im Folgenden werden wir das Vorhandensein eines Musters mit re.search() und geben dann eine iterierbare Liste von Catches zurück. Zum Schluss wird jeder Catch unter Verwendung der Klammerschreibweise gedruckt, um den Rückgabewert des Match-Objekts aus dem Match-Objekt auszuwählen.

s = 'he33llo 42 I\'m a 32 string 30 444.4 12,001'

if re.search(p, s) is not None:
    for catch in re.finditer(p, s):
        print(catch[0]) # catch is a match object

Rückgabe:

33
42
32
30
444.4
12,001

0 Stimmen

Dies akzeptiert auch eine Zahl, die mit einem Punkt endet, wie "30". Sie brauchen so etwas wie das: "[ \d ]+[\, \d ]*[ \. ]{0,1}[ \d ]+"

34voto

Sidon Punkte 1198

Ich war auf der Suche nach einer Lösung, um die Masken von Zeichenketten zu entfernen, insbesondere von brasilianischen Telefonnummern, und dieser Beitrag hat mir nicht geantwortet, sondern mich inspiriert. Dies ist meine Lösung:

>>> phone_number = '+55(11)8715-9877'
>>> ''.join([n for n in phone_number if n.isdigit()])
'551187159877'

1 Stimmen

Schön und einfach, und wohl besser lesbar als das ebenfalls korrekte, aber weniger bekannte filter() Funktionstechnik: ''.join(filter(str.isdigit, phone_number))

3 Stimmen

Nett, aber die Umwandlung in eine Liste ist unnötig. Es kann leicht verbessert werden als ''.join(n for n in phone_number if n.isdigit()) .

25voto

AndreiS Punkte 264
# extract numbers from garbage string:
s = '12//n,_@#$%3.14kjlw0xdadfackvj1.6e-19&*ghn334'
newstr = ''.join((ch if ch in '0123456789.-e' else ' ') for ch in s)
listOfNumbers = [float(i) for i in newstr.split()]
print(listOfNumbers)
[12.0, 3.14, 0.0, 1.6e-19, 334.0]

5 Stimmen

Willkommen bei SO und danke, dass Sie eine Antwort gepostet haben. Es ist immer eine gute Praxis, einige zusätzliche Kommentare zu Ihrer Antwort hinzuzufügen und zu erläutern, warum sie das Problem löst, anstatt nur einen Codeschnipsel zu posten.

0 Stimmen

Funktionierte in meinem Fall nicht. Nicht viel anders als die Antwort oben

0 Stimmen

ValueError: Konnte String nicht in Float umwandeln: 'e' und funktioniert in manchen Fällen nicht :(

23voto

Antonin GAVREL Punkte 7751

Bei Telefonnummern können Sie einfach alle nicht-ziffrigen Zeichen ausschließen mit \D in Regex:

import re

phone_number = "(619) 459-3635"
phone_number = re.sub(r"\D", "", phone_number)
print(phone_number)

El r en r"\D" steht für Rohstring . Sie ist notwendig. Ohne sie wird Python als \D als Escape-Zeichen.

21voto

Mit der folgenden Regex können Sie

lines = "hello 12 hi 89"
import re
output = []
#repl_str = re.compile('\d+.?\d*')
repl_str = re.compile('^\d+$')
#t = r'\d+.?\d*'
line = lines.split()
for word in line:
        match = re.search(repl_str, word)
        if match:
            output.append(float(match.group()))
print (output)

mit findall re.findall(r'\d+', "hello 12 hi 89")

['12', '89']

re.findall(r'\b\d+\b', "hello 12 hi 89 33F AC 777")

['12', '89', '777']

0 Stimmen

Sie sollten zumindest die Regex kompilieren, wenn Sie nicht mit findall()

2 Stimmen

repl_str = re.compile('\d+.?\d*') sein sollte: repl_str = re.compile('\d+\.?\d*') Für ein reproduzierbares Beispiel mit Python 3.7 re.search(re.compile(r'\d+.?\d*'), "42G").group() '42G' re.search(re.compile(r'\d+\.?\d*'), "42G").group() '42'

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X