Seite 1 von 1

String aufteilen

Verfasst: Dienstag 31. März 2009, 15:26
von #cousin#
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?

Verfasst: Dienstag 31. März 2009, 15:34
von Dauerbaustelle
Wie meinen, wenn das "01" ein Byte ist? Ein Byte wäre "00000001".

Verfasst: Dienstag 31. März 2009, 16:02
von b.esser-wisser
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")

Verfasst: Dienstag 31. März 2009, 16:05
von #cousin#
@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.

Verfasst: Dienstag 31. März 2009, 17:20
von numerix
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 ...

Verfasst: Dienstag 31. März 2009, 18:57
von b.esser-wisser
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

Verfasst: Dienstag 31. März 2009, 22:41
von #cousin#
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!

Verfasst: Mittwoch 1. April 2009, 09:48
von sma
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