Seite 1 von 1

Zahlen aus String auslesen

Verfasst: Donnerstag 15. März 2007, 11:18
von morph
Hallo,

ich habe hier einen seriellen Temperatur- und Luftfeuchtigkeitssensor, den ich gerne auslesen möchte. Das funktioniert soweit mit pyserial auch gut, allerdings erhalte ich dann einen string, der etwa folgendermaßen aussieht: "temperature=24.0°C humidity=46%"

Nun möchte ich die Zahlenwerte aber Variablen zuweisen, um diese weiterverarbeiten zu können, so dass nachher die Variable temp den Wert 24.0 und die Variable hum den Wert 46 bekommt.

Leider stehe ich da jetzt auf dem Schlauch. Ich habe zwar schon überlegt, den String zeichenweise auszulesen und das Ergebnis, wenn es sich um eine Zahl oder einen Punkt handelt in einen weitern String zu schreiben und diesen dann nach float zu konvertieren, aber das ganze kommt mir doch sehr umständlich vor. Hat jemand einen Tip, wie ich das ganze eleganter und mit weniger Aufwand hinbekommen kann?

Verfasst: Donnerstag 15. März 2007, 11:28
von CM
Hoi,

wenn es wirklich keine einfachere Weise gibt (nämlich die Werte direkt zu erhalten), dann kannst Du es so probieren:

Code: Alles auswählen

>>> s = "temperature=24.0°C humidity=46%"
>>> temp, hum = float(s[12:16]), int(s[29:31])
>>> temp
24.0
>>> hum
46
Das wäre einze Zeile relevanter Code. Ärgerlich wäre es, wenn sich die Positionen der Zahlen verändern würden oder auch noch andere Strings übergeben würden. In dem Fall würde ich zu einem "Eigenbauminiparser" auf der Basis von regulären Audrücken (re-modul) empfehlen. Ist vielleicht ein overkill, aber u. U. besser als viele Ausnahmen gesondert zu behandeln.

Gruß,
Christian

Verfasst: Donnerstag 15. März 2007, 11:29
von Käptn Haddock
Du kannst mit Regular Expressions den String nach den Zahlen durchsuchen und die resultierenden Teilstrings dann in Zahlen umwandeln.

Gruß Uwe

Verfasst: Donnerstag 15. März 2007, 11:31
von PmanX
genügt da folgende RegEx nicht?

Code: Alles auswählen

'temperature=(\d+.\d)°C humidity=(\d+)%'
Gruß P.

Verfasst: Donnerstag 15. März 2007, 12:41
von CM
Eigentlich schon, fand es nur einen Overkill und meinte regexes sind nur interessant, wenn sich das Schema des Strings ab und an ändert. (Code gewinnt ja oft nicht gerade an Lesbarkeit, wenn regexes darin rumschwirren ;-).)

Ansonsten, der Vollständigkeit halber:

Code: Alles auswählen

>>> import re
>>> x = re.compile('temperature=(\d+.\d)°C humidity=(\d+)%')
>>> match = re.match(x,s)
>>> temp, hum = float(match.groups()[0]), int(match.groups()[1])
>>> print temp, hum
24.0 46
Nur ist das eben keine Vereinfachung zum ersten Beispiel, im Gegenteil. Ggf. muß der Ausdruck halt angepasst werden, weniger explizit, je nachdem, wie der Datenfluß so aussieht.

Gruß,
Christian

edit: ups, match.group(1) und (2) ginge natürlich auch.

Verfasst: Donnerstag 15. März 2007, 13:03
von mawe
Wenn die Reihenfolge immer gleich ist, kann man ja auch das machen:

Code: Alles auswählen

In [1]: s = "temperature=24.0°C humidity=46%"

In [2]: pattern = re.compile("\d+(?:\.\d+)?")

In [3]: pattern.findall(s)
Out[3]: ['24.0', '46']

Verfasst: Donnerstag 15. März 2007, 14:38
von PmanX
CM hat geschrieben:Eigentlich schon, fand es nur einen Overkill und meinte regexes sind nur interessant, wenn sich das Schema des Strings ab und an ändert. (Code gewinnt ja oft nicht gerade an Lesbarkeit, wenn regexes darin rumschwirren ;-).)
...
Unsere Posts liegen wenige Minuten auseinander.
Heißt: Mein Vorschlag ist unabhängig von Deinem.

Dein Vorschlag sollte aber bei einstelligen Werten auf die Nase fallen.

Edit:

Code: Alles auswählen

cre = re.compile(r'temperature=(?P<TEMP>\d+.\d).C humidity=(?P<LF>\d+)%')
m = cre.search('temperature=24.0°C humidity=46%')
temp, luftf = m.group('TEMP'),  m.group('LF')