MLenz: Regex zum Listenzerlegen gesucht

Hallo,

bei sowas mache ich mir leider immer recht schnell einen Knoten ins Hirn. Vielleicht hat ja von euch jemand Spaß am Schreiben von Regex und kann mir weiterhelfen.

Gesucht wird ein regulärer Ausdruck, mit dem ich eine Liste in ihre mit Komma getrennte Einzelteile zerlegen kann, z.B. String1,String2,String3.
Das Problem dabei ist, dass ein Komma auch im String vorkommen kann solange es escaped ist "," und da auch das Escapezeichen vorkommen darf sind solche Sachen möglich:
String1,St,ring2,St\\,ring3\,String4 - das sind 4 Strings.

Ich hab's die letzten zwei Stunden vergeblich versucht.

Ciao,
Martin

  1. Hi MLenz!

    String1,St,ring2,St\\,ring3\,String4 - das sind 4 Strings.
    Ich hab's die letzten zwei Stunden vergeblich versucht.

    Ersetze doch einfach "," durch eine Zeichenkette, die im Text nicht vorkommt und splitte dann mit explode() am Komma.
    Danach kannst du das ersetzte "," wieder rücksetzen.

    MfG H☼psel

    --
    "It's amazing I won. I was running against peace, prosperity, and incumbency."
    George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
    Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)
    1. Ersetze doch einfach "," durch eine Zeichenkette, die im Text nicht vorkommt und splitte dann mit explode() am Komma.

      Undefined subroutine &main::explode called at http://forum.de.selfhtml.org/my/?t=176835&m=1164094 line 4.

      *vbg*

      Siechfred

      --
      Obacht, hinter jedem noch so kleinen Busch könnte ein Indianer sitzen!
    2. Hallo,

      String1,St,ring2,St\\,ring3\,String4 - das sind 4 Strings.
      Ich hab's die letzten zwei Stunden vergeblich versucht.
      Ersetze doch einfach "," durch eine Zeichenkette, die im Text nicht vorkommt und splitte dann mit explode() am Komma.
      Danach kannst du das ersetzte "," wieder rücksetzen.

      Falls eine ungerade Anzahl Backslashes vor dem Komma steht darf dort aber nicht gesplittet werden. Umgehen sich die anzusehen funktioniert also nicht.

      Martin

      1. Hi MLenz!

        String1,St,ring2,St\\,ring3\,String4 - das sind 4 Strings.
        Ich hab's die letzten zwei Stunden vergeblich versucht.
        Ersetze doch einfach "," durch eine Zeichenkette, die im Text nicht vorkommt und splitte dann mit explode() am Komma.
        Danach kannst du das ersetzte "," wieder rücksetzen.
        Falls eine ungerade Anzahl Backslashes vor dem Komma steht darf dort aber nicht gesplittet werden.

        Ja, du hast recht. Dann ersetzt du eben vorher noch alle "\".

        MfG H☼psel

        --
        "It's amazing I won. I was running against peace, prosperity, and incumbency."
        George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
        Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)
  2. gudn tach!

    Gesucht wird ein regulärer Ausdruck, mit dem ich eine Liste in ihre mit Komma getrennte Einzelteile zerlegen kann, z.B. String1,String2,String3.
    Das Problem dabei ist, dass ein Komma auch im String vorkommen kann solange es escaped ist "," [...]

    meine erste spontane idee ist

    split /(?<=[^\\](?:\\\\)*),/, $str;

    also ein komma, dem ein string vorausgeht, fuer den gilt: er beginnt mit einem nicht-backslash gefolgt von einer geraden anzahl (0 ist gerade) von backslashes.

    das wird allerdings nicht funzen, weil perl keine variable-length look-behind assertions unterstuetzt. zumindest war das bis etwa perl 5.9 so. hast du perl 5.10? denn dann kannst du folgendes probieren:

    split /[^\\](?:\\\\)*\K,/, $str;

    das ist das gleiche in gruen, aber erlaubt var-length. siehe dazu [http://perldoc.perl.org/perlre.html].

    alternativ dazu kannst du in aelteren perl-versionen auch einfach
    split /([^\\](?:\\\\)*),/, $str;
    benutzen, musst dann jedoch die entsprechenden zerhackten array-elemente wieder irgendwie zusammenfuehren.

    ich bin mir nicht sicher, aber glaube, dass wir solche probleme schon mal im forum besprachen, evtl. findest du via forumssuche bessere loesungen.

    prost
    seth

    1. Hi Seth,

      das wird allerdings nicht funzen, weil perl keine variable-length look-behind assertions unterstuetzt. zumindest war das bis etwa perl 5.9 so.

      Das ist naheliegend, hatte ich aber gar nicht probiert weil mir die Einschränkung bekannt ist. Und die gibt's auch in 5.10 noch.

      hast du perl 5.10? denn dann kannst du folgendes probieren:

      split /[^\\](?:\\\\)*\K,/, $str;

      das ist das gleiche in gruen, aber erlaubt var-length. siehe dazu [http://perldoc.perl.org/perlre.html].

      Wow, das ist genial. \K war mir nicht bekannt.
      Die Schreibweise mit look-behind gefällt mir auch weiterhin besser, aber ich werd da jetzt nicht rummotzen, mit \K funktioniert's ja tadellos.

      ich bin mir nicht sicher, aber glaube, dass wir solche probleme schon mal im forum besprachen, evtl. findest du via forumssuche bessere loesungen.

      Ich werd' nochmal suchen. Vor meiner Anfrage hatte ich das zwar schon gemacht, aber bei der Wahl der richtigen Suchbegriffe greife ich anscheinend immer daneben.

      Vielen Dank,
      Martin