PYTHON Zahl aus string ermitteln

Gast #7113920
Hallo,

der in python implementierte UDP Server erhät ein Frame das so aussieht: 
FRAME:50

Nun möchte ich nur die Zahl in ienem Integer speichern. Wie kann ich 
dies in python realisieren? Wie unten gezeigt habe ich mal die Funktion 
findall eingesetzt.
Allerdings erhalte ich einen Vector mit mehrern Werden. Darin ist die 
Zahl 50 abgelegt. Wie kann ich nur die Zahl erhausziehen?
1
 data, address = serverSocket.recvfrom(1024)
2

3
 length = len(data)
4

5
 header_frame = data.decode('utf-8')
6
 zahl = re.findall('([0-9]*)', header_frame)
frame='FRAME:50'
print(frame)
a = frame.split(':')
print(a)
try:
    print(a[1])
except IndexError:
    print('keinen Doppelpunkt gefunden')

try:
    nummer = int(a[1])
except (IndexError, ValueError):
    print('keine Zahl gefunden')
else:
    print ('Nummer: ', nummer)
Gast
Danke funktioniert allerdings muss ich das ganze in einer while Schleife 
ausführen. Das mit dem print ist dann ein Problem. Wie kann ich die 
gefunden Zahl in eine Variable ablegen?
Gast
dev schrieb:
> Das mit dem print ist dann ein Problem. Wie kann ich die
> gefunden Zahl in eine Variable ablegen?

Wie wäre es mit
1
import re
2
data ="49FRAME:50 51"
3
zahlen = [int(x) for x in re.findall(r"\d+", data)]

Dann sind alle Zahlen als Integer in einer List.
Aber mal grundsätzlich wie sinnvoll ist es einfach alle Zahlen zu 
konvertieren und dann hoffen das da, was Gutes bei rauskommt? Wie sieht 
denn ein echter kompletter Frame aus? Vielleicht ist es sinnvoll eine 
Art Parser zu schreiben, welchen den Frame versteht und dann nur die 
Werte welche man wirklich braucht als integer zu parsen.
Gast
dev schrieb:
> Was ich leider nicht tun kann ist, nach jedem ankommenden Frame ein
> Acknowledge Frame zu senden aufgrund von Verzögerungen durch das
> Mobilfunknetz.

Deswegen verwendet man dafür auch besser TCP, das kann damit umgehen.
dev schrieb:
> Danke funktioniert allerdings muss ich das ganze in einer while Schleife
> ausführen. Das mit dem print ist dann ein Problem. Wie kann ich die
> gefunden Zahl in eine Variable ablegen?

Lieber TO, ich weiß ja: Du hast JETZT ein Problem und möchtest es JETZT 
lösen, und zwar bitte so schnell wie möglich. Das verstehe ich, aber 
trotzdem ist Dein Ansatz leider nicht sonderlich zielführend -- denn am 
Ende möchtest Du mit den gewonnenen Daten ja irgendetwas machen -- und 
wie soll das gehen, solange Du keine Ahnung von Deinem Werkzeug hast?

Meine ebenso wohlwollende wie dringende Empfehlung ist daher, erstmal 
einen Schritt von Deinem Problem zurückzutreten, und ein Python-Tutorial 
durchzuarbeiten. Davon habe ich unten zwei verlinkt: das erste [1] ist 
der Goldstandard von den Machern der Sprache selbst, das zweite [2] ist 
eine deutsche Übersetzung einer älteren Version des vorherigen 
Tutorials, wenn Dein Englisch vielleicht nicht so gut ist, und wenn Dir 
beide nicht gefallen, haben die Entwickler von Python noch einige 
Empfehlungen für weitere gute Tutorials unter [3].

Was Dein eigentliches Problem angeht, Deine Frames zu parsen, gibt es 
dazu viele mögliche Ansätze. Ein üblicher Ansatz wären die hier im 
Thread bislang gezeigten, also: mit str.split(), re.findall() oder einer 
List Comprehension, ein wesentlich weiter gehender Ansatz wäre hingegen, 
einen Parsergenerator wie Lark [4], PyPEG [5] oder Parsimonius [6] zu 
benutzen. Ein paar allgemeine, grundsätzliche Anmerkungen hinsichtlich 
solcher Parserwerkzeuge findest Du bei Mario Tomasetti.

Herzlich willkommen im Python-Universum, viel Spaß, Erfolg und Glück! 
;-)


[1] https://docs.python.org/3/tutorial/
[2] https://py-tutorial-de.readthedocs.io/de/python-3.3/
[3] https://wiki.python.org/moin/BeginnersGuide
[4] https://lark-parser.readthedocs.io/en/latest/
[5] https://fdik.org/pyPEG/
[6] https://github.com/erikrose/parsimonious
[7] https://tomassetti.me/parsing-in-python/
Gast
Du brauchst auch kein Ack frame senden, sondern musst Dir ein Protokol 
ausdenken, ob nun auf UDP o. TCP.

1. Magic Key
2. Sequenznummer (UDP) o. Datalength (TCP)
3. Payload z.b. als Json string
4. CRC
5. Endframe (bei TCP)

Magickey damit du weisst das es von deinem Client kommt
Mit der Sequenzenummer kannst du feststellen, ob ein Frame verloren 
gegangen ist
Bei TCP musst du die länge mitgeben, weil der Frame aufgteilt wird
Payload Json (lässt sich einfach parsen)
CRC Zur Sicherheit
Endframe damit du beim TCP weisst dass das ganze Frame kam

Schau Dir mal Mqtt an, dafür gibt es fertige Libs und Broker.
Gast
Hallo Thorben,

vielen Dank für deinen hilfreichen Beitrag.

Ich würde UDP bevorzugen. Allerdings ist mir nicht ganz klar, woher der 
Sender weiß das auch alle Frames angekommen sind oder auch nicht? Der 
Empfänger müsste doch dann am Ende ein ACK Frame an den Sender 
versenden.
Gast
dev schrieb:
> Ich würde UDP bevorzugen. Allerdings ist mir nicht ganz klar, woher der
> Sender weiß das auch alle Frames angekommen sind oder auch nicht? Der
> Empfänger müsste doch dann am Ende ein ACK Frame an den Sender
> versenden.

Bei UDP weiss der Sender nicht ob ein Paket angekommen ist, und der 
Empfänger weiss nicht ob eins verloren gegangen ist. Du bist anscheinend 
gerade dabei ein Protokoll zu entwerfen das diese Zusicherungen oberhalb 
von UDP nachrüstet. Das ist aber recht anspruchsvoll. Zum Beispiel kann 
auch dein ACK-Paket verloren gehen ...

LG, Sebastian

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 4 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.