Seite 1 von 1

String splitten - aber nicht immer

Verfasst: Montag 21. Juli 2014, 14:40
von finswimmer77
Hallo,

gegeben sei folgender Beispielstring:

row = "a,b,c[d,e],f"

Ich möchte diesen String nun an jedem Komma splitten, außer das Komma erscheint innerhalb der eckigen Klammern. Gibt's da ne Möglichkeit?

fin swimmer

Re: String splitten - aber nicht immer

Verfasst: Montag 21. Juli 2014, 14:59
von darktrym
regex.

Re: String splitten - aber nicht immer

Verfasst: Montag 21. Juli 2014, 15:03
von finswimmer77
darktrym hat geschrieben:regex.
Das hab ich befürchtet. Mit regex steh ich seit eh und je auf dem Kriegsfuß. Hättest du einen Codeschnipsel für mich?

Danke

fin swimmer

Re: String splitten - aber nicht immer

Verfasst: Montag 21. Juli 2014, 15:08
von mutetella
Mit dem re-Module könnte eine Lösung so aussehen:

Code: Alles auswählen

import re

def limited_split(s):
    desired = ''.join(re.split(r'\[.*\]', s))
    return desired.split(',')

Code: Alles auswählen

>>> limited_split('a,b,c[d,e],f')
>>> ['a', 'b', 'c', 'f']
mutetella

Re: String splitten - aber nicht immer

Verfasst: Montag 21. Juli 2014, 15:17
von finswimmer77
Danke für die Antwort.

Das re-Modul wird vermutlich die Lösung liefern. So ganz erhalte ich mit deinem Beispiel mein Ziel aber noch nicht. Ziel sollte sein

Code: Alles auswählen

['a', 'b', 'c[d,e]', 'f']

Re: String splitten - aber nicht immer

Verfasst: Montag 21. Juli 2014, 15:29
von mutetella
@finswimmer77
Dann musst Du eben die regex '\[.*\]' dahingehend ändern... :wink:

Ich weiß ja nicht, was Du vorhast, aber das ganze riecht sehr eigenartig... :wink:

mutetella

Re: String splitten - aber nicht immer

Verfasst: Montag 21. Juli 2014, 16:41
von Sirius3
@mutetella: Für was man da ein extra split braucht ist mir nicht klar

Code: Alles auswählen

values = re.findall(r'(?:[^,\[\]]|\[.*?\])+', row)

Re: String splitten - aber nicht immer

Verfasst: Montag 21. Juli 2014, 18:46
von mutetella
Sirius3 hat geschrieben:Für was man da ein extra split braucht ist mir nicht klar
Du musst eben noch viel lernen... :mrgreen:

mutetella

Re: String splitten - aber nicht immer

Verfasst: Dienstag 22. Juli 2014, 09:07
von finswimmer77
Sirius3 hat geschrieben:@mutetella: Für was man da ein extra split braucht ist mir nicht klar

Code: Alles auswählen

values = re.findall(r'(?:[^,\[\]]|\[.*?\])+', row)
Vielen Dank! Das scheint genau das zu machen, was ich möchte. Jetzt werd ich nur wieder ne ewigkeit brauchen, zu verstehen was der regex eigentlich macht.

fin swimmer

Re: String splitten - aber nicht immer

Verfasst: Dienstag 22. Juli 2014, 10:48
von nezzcarth
finswimmer77 hat geschrieben: Vielen Dank! Das scheint genau das zu machen, was ich möchte. Jetzt werd ich nur wieder ne ewigkeit brauchen, zu verstehen was der regex eigentlich macht.
Na ja, die Alternative wäre, das selbst per Hand zu machen, in dem du den String Zeichen für Zeichen durchgehst, und dir merkst, ob du dich gerade in einer eckigen Klammer befindest, oder nicht. Das, was man da schreibtt, ist dann vom Effekt her eine (schlechtere) Implementation eines kleinen Subsets dessen, was mit regulären Ausdrücken möglich ist. Das macht man üblicherweise nicht, weil reguläre Ausdrücke zwar vielleicht etwas kompliziert zu schreiben, sonst aber für den Zweck überlegen sind.

Re: String splitten - aber nicht immer

Verfasst: Dienstag 22. Juli 2014, 12:08
von Hyperion
Ein Ansatz in die Richtung State-Machine habe ich einst implementiert: https://github.com/Lysander/snippets/bl ... nslator.py

@nezzcarth: Pauschal kann man das nicht sagen - ist die Struktur tatsächlich rekursiv aufgebaut, kommst Du mit RegExps nicht weit... für eine feste Ausnahme wie in diesem Falle hast Du natürlich recht.

Re: String splitten - aber nicht immer

Verfasst: Dienstag 22. Juli 2014, 12:10
von BlackJack
@nezzcarth: Es gäbe noch die Möglichkeit eine Parserbibliothek zu verwenden. Ist auch übertrieben, aber vielleicht lesbarer.

Re: String splitten - aber nicht immer

Verfasst: Dienstag 22. Juli 2014, 12:13
von /me
Sirius3 hat geschrieben:

Code: Alles auswählen

values = re.findall(r'(?:[^,\[\]]|\[.*?\])+', row)
Jetzt muss ich mir nur noch erschließen, wie die non-capturing Group dazu beiträgt den kompletten String 'c[d,e]' zu liefern. Das erste Muster im regulären Ausdruck ist klar, das zweite auch - aber wodurch liefert mir der Gesamtausdruck das Ergebnis das er liefert? *grübel*

Re: String splitten - aber nicht immer

Verfasst: Dienstag 22. Juli 2014, 12:24
von BlackJack
@/me: Durch das '+' und das nichts in der Gruppe auf Kommas ausserhalb von eckigen Klammern matcht.

Re: String splitten - aber nicht immer

Verfasst: Dienstag 22. Juli 2014, 12:31
von /me
BlackJack hat geschrieben:@/me: Durch das '+' und das nichts in der Gruppe auf Kommas ausserhalb von eckigen Klammern matcht.
Ach klar. Das '+' hatte ich nicht wirklich wahrgenommen. Danke.