String aufteilen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
#cousin#
User
Beiträge: 25
Registriert: Mittwoch 18. März 2009, 22:56
Wohnort: Mannheim
Kontaktdaten:

Dienstag 31. März 2009, 15:26

Hi Zusammen,

ich hab mehrere Strings die ähnlich aussehen wie der folgende:

0200080B0100010000051188A00008130207D707100C1B0801

(das ist ein String mit HEX Werten)

nun möchte ich, dass der String immer bei 01 aufgeteilt wird, aber eben nur, wenn das 01 auch ein Byte ist. Also, als Ergebnis hätte ich gerne

0200080B - 01 - 00 - 01 - 0000051188A00008130207D707100C001008 - 01

und nicht

0200080B - 01 - 00 - 01 - 0000051188A00008130207D707100C0 - 01 - 008 - 01

leider bewirkt string.split("01") Letzteres :?

(die 01en in den beiden aufgeteilten Strings müssen später nicht mehr erhalten sein)

kann mir Jemand von euch dabei weiterhelfen?
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Dienstag 31. März 2009, 15:34

Wie meinen, wenn das "01" ein Byte ist? Ein Byte wäre "00000001".
Benutzeravatar
b.esser-wisser
User
Beiträge: 272
Registriert: Freitag 20. Februar 2009, 14:21
Wohnort: Bundeshauptstadt B.

Dienstag 31. März 2009, 16:02

Wie verarbeitest du diese strings weiter?
hilft dir sowas?

Code: Alles auswählen

In[21]: h = "0200080B0100010000051188A00008130207D707100C1B0801"

In [22]: h.decode("hex")
Out[22]: '\x02\x00\x08\x0b\x01\x00\x01\x00\x00\x05\x11\x88\xa0\x00\x08\x13\x02\x
07\xd7\x07\x10\x0c\x1b\x08\x01'

In [23]: _.split("\x01") # das "01" wird dabei geloescht
Out[23]:
['\x02\x00\x08\x0b',
 '\x00',
 '\x00\x00\x05\x11\x88\xa0\x00\x08\x13\x02\x07\xd7\x07\x10\x0c\x1b\x08',
 '']
In [24]: len(h.decode("hex")) # ab hier nur noch halb soviele Bytes...
Out[24]: 25
hth, Jörg

ps.: für den Fall der Fälle gibt's natürlich auch str.encode("hex")
Wir haben schon 10% vom 21. Jahrhundert hinter uns!
#cousin#
User
Beiträge: 25
Registriert: Mittwoch 18. März 2009, 22:56
Wohnort: Mannheim
Kontaktdaten:

Dienstag 31. März 2009, 16:05

@Dauerbaustelle:

in HEX stehen immer 2 Zeichen für einen Wert...evtl. war hier das Wort Byte etwas verwirrend


@b.esser-wisser:

das werde ich gleich mal testen, danke dafür. Danach wandel ich diese Teile in DEC und ASCII um, sollte also auch mit \x01 anstatt 01 gehen.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Dienstag 31. März 2009, 17:20

Bei der gezeigten Methode über hex gehen durch das split() die "01"-Einträge verloren. Das könnte man über fortgesetzte Anwendung von partition() statt split beheben.

Oder man macht es ganz primitiv zu Fuß: :wink:

Code: Alles auswählen

s = "0200080B0100010000051188A00008130207D707100C1B0801"

def split01(s):
    result = [""]
    for p in xrange(0, len(s), 2):
        t = s[p:p+2]
        if t == "01":
            result.extend([t,""])
        else:
            result[-1] += t
    return result

print split01(s)
Liefert:
['0200080B', '01', '00', '01', '0000051188A00008130207D707100C1B08', '01', '']

Falls der letzte leere Eintrag stört, fällt dir dafür sicher eine Lösung ein.
Ein "return result[:-1]" ist allerdings nicht die Lösung ...
Benutzeravatar
b.esser-wisser
User
Beiträge: 272
Registriert: Freitag 20. Februar 2009, 14:21
Wohnort: Bundeshauptstadt B.

Dienstag 31. März 2009, 18:57

Hier noch eine RegEx-Lösung

Code: Alles auswählen

import re, itertools
s = "0200080B0100010000051188A00008130207D707100C1B0801"
MAGIC = r"""(?x)    # verbose-flag, d.h.: lesbar ;)
  (                 # finde:
    (?:
      [\dA-Fa-f]{2} # Zwei Hex-Zeichen...
    )*?             # so oft, bis die nächste Gruppe match't
  )                 # als Gruppe 0
  ( 01 )            # der Trenner (Gruppe 1)"""
parts = list(itertools.chain(*re.findall(MAGIC, s)))
# ohne extra-liste :
parts = list(itertools.chain(*(m.groups() for m in re.finditer(MAGIC, s))))
print parts
Prädikat: "unnötig unlesbar" ;)
Ich kriege es aber nicht hin, mit nur einer gruppe zu match'en, so dass re.findall() gleich das Ergebnis liefert, evtl. fällt mir da noch was ein.

hth, Jörg
#cousin#
User
Beiträge: 25
Registriert: Mittwoch 18. März 2009, 22:56
Wohnort: Mannheim
Kontaktdaten:

Dienstag 31. März 2009, 22:41

b.esser-wisser hat geschrieben:Wie verarbeitest du diese strings weiter?
hilft dir sowas?

Code: Alles auswählen

In[21]: h = "0200080B0100010000051188A00008130207D707100C1B0801"

In [22]: h.decode("hex")
Out[22]: '\x02\x00\x08\x0b\x01\x00\x01\x00\x00\x05\x11\x88\xa0\x00\x08\x13\x02\x
07\xd7\x07\x10\x0c\x1b\x08\x01'

In [23]: _.split("\x01") # das "01" wird dabei geloescht
Out[23]:
['\x02\x00\x08\x0b',
 '\x00',
 '\x00\x00\x05\x11\x88\xa0\x00\x08\x13\x02\x07\xd7\x07\x10\x0c\x1b\x08',
 '']
In [24]: len(h.decode("hex")) # ab hier nur noch halb soviele Bytes...
Out[24]: 25
hth, Jörg

ps.: für den Fall der Fälle gibt's natürlich auch str.encode("hex")

Vielen Dank für die ganzen Hinweise und Vorschläge. die Methode von Jörg klappt super und die 01en brauch ich eh nicht.

Nochmals vielen Dank für den schnellen Support an alle!
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Mittwoch 1. April 2009, 09:48

Mein Vorschlag:

Code: Alles auswählen

a = "010200080B0100010000051188A00008130207D707100C1B080101"
a = re.sub("(..)", "\\1 ", a)  # aufspalten
a = re.sub("01 ", "-01-", a)  # 01 abtrennen
a = re.sub("^-|-$|-(?=-)| ", "", a)  # bereinigen
print a
Stefan
Antworten