Marko: Ein kleines Regex-Rätsel

Hallo, ich hab ein Rätsel für gemacht: Was matcht dieses Regex-Pattern (Perl Syntax)?

$pattern = '/(?<=^).(?<![^r])(?=(?(?!.)d|(?P<a>e))).(g(?=(?(?=[a-zA-Z0-9])(?P=a)|f))|(?<![^g])(?(?=[a-zA-Z0-9])(?P=a)|c)){2}(?(?=[a-zA-Z0-9])x|y)(?![^$])/';

Viel Spass,

Marko

  1. Was matcht dieses Regex-Pattern (Perl Syntax)?

    Dieses Regex-Pattern macht mich narrisch! Möglichst kompakt und unübersichtlich codieren, damit es andere nur schwer verstehen (der Author selbst auch, wenn er es nach 6 Wochen wieder liest).

    1. Hallo Günther

      Möglichst kompakt und unübersichtlich codieren, damit es andere nur schwer verstehen (der Author selbst auch, wenn er es nach 6 Wochen wieder liest).

      Da es sich um ein Rätsel handelt, ist es nicht für den Gebrauch bestimmt, und absichtlich ein wenig umständlich geschrieben.

      Wegen der übersichtlichen Kodierung würde mich aber interessieren, da ich das wirklich nicht weiss, wie man Regex-Patterns übersichtlich machen kann (also nur im Pattern drin, nicht mit PHP-String-Concats auf mehrere Zeilen verteilen).

      Gruss, Marko

      1. Hallo Marko,

        Wegen der übersichtlichen Kodierung würde mich aber interessieren, da ich das wirklich nicht weiss, wie man Regex-Patterns übersichtlich machen kann (also nur im Pattern drin, nicht mit PHP-String-Concats auf mehrere Zeilen verteilen).

        Du kannst "whitespace" und Kommentare verwenden wenn Du den "x"-Modifier setzt.

        Viele Grüße

        Stefan

        --
        bythewaythewebsuxgoofflineandenjoytheday
  2. echo $begrüßung;

    Hallo, ich hab ein Rätsel für gemacht: Was matcht dieses Regex-Pattern (Perl Syntax)?
    $pattern = '/(?<=^).(?<![^r])(?=(?(?!.)d|(?P<a>e))).(g(?=(?(?=[a-zA-Z0-9])(?P=a)|f))|(?<![^g])(?(?=[a-zA-Z0-9])(?P=a)|c)){2}(?(?=[a-zA-Z0-9])x|y)(?![^$])/';

    Gesucht wird ein beliebiges Zeichen (.), dem ein Anfang (^) vorangehen muss, der aber nicht ins Ergebnis einfließt (positive Lookbehind Assertion: (?<=...) ). Das ist ein recht sinnloses Konstrukt, weil der Anfang sowieso nicht ins Ergebnis mit einfließt. Hier hätte es ein ^. auch getan.

    Und nun habe ich die Lust verloren ...

    echo "$verabschiedung $name";

    1. Hallo

      Das ist ein recht sinnloses Konstrukt, weil der Anfang sowieso nicht ins Ergebnis mit einfließt. Hier hätte es ein ^. auch getan.

      Ich weiss. Ich will nochmals betonen, dass es sich um ein Rätsel handelt, und deswegen (natürlich) mit Hindernissen gespickt ist.

      Gut, dass die Verwirrung bei dir nichts gebracht hat. Was ist mit dem Rest? ;)

      Gruss, Marko

  3. $pattern = '/(?<=^).(?<![^r])(?=(?(?!.)d|(?P<a>e))).(g(?=(?(?=[a-zA-Z0-9])(?P=a)|f))|(?<![^g])(?(?=[a-zA-Z0-9])(?P=a)|c)){2}(?(?=[a-zA-Z0-9])x|y)(?![^$])/';

    Hallo Marko,

    der Anfang (?<=^).(?<![^r]) ist äquivalent mit ^r.

    Weiter habe ich momentan auch keine Lust, vor allem weil ich mich mit der Perl-Syntax nicht auskenne :-)

    Gruß Uwe

    1. Hallo Uwe

      der Anfang (?<=^).(?<![^r]) ist äquivalent mit ^r.

      Korrekt ;)

      Gruss

      1. Hallo Marko,

        (?=(?(?!.)d|(?P<a>e))). <=> e

        Aufgeschlüsselt von außen nach innen

        (?=e). <=> e

        e -> (?(?!.)d|(?P<a>e))

        (? ... ) -> wirkungslos

        (?!.)d <=> (?=\n)d -> kann niemals eintreten

        (?P<a>e) <=> e

        Als nächstes kommt ein g, wir sind also bei ^reg, aber jetzt habe ich keine Zeit mehr.

        Gruß Uwe

        1. Hallo Uwe,

          e -> (?(?!.)d|(?P<a>e))

          (? ... ) -> wirkungslos

          Ist nicht wirkungslos, es leitet einen Konditionsblock ein. (?(if)then|else).

          Als nächstes kommt ein g, wir sind also bei ^reg, aber jetzt habe ich keine Zeit mehr.

          Korrekt, aber die Begründung für das g fehlt noch.

          Gruss, Marko

          1. Hallo Marko,

            »»Ist nicht wirkungslos, es leitet einen Konditionsblock ein. (?(if)then|else).

            Ok :-), ich drück's mal so aus:

            (?=(?(?!.)d|(?P<a>e))) <=> (?=(?!.)d|(?P<a>e))

            Und nun zu »ge« in »regex«. Wollte man dies in Worten beschreiben, müsste man die Romanform wählen ;-)
            Den Bezugstext »regex« schreibe ich in Großbuchstaben, damit man besser unterscheiden kann, wann vom Bezugstext und wann vom Muster die Rede ist, also »REGEX«.

            Wir haben:
            (g(?=(?(?=[a-zA-Z0-9])(?P=a)|f))|(?<![^g])(?(?=[a-zA-Z0-9])(?P=a)|c)){2}

            Diesen Ausdruck vereinfache ich:
            (?P=a) <=> e
            (?(?=[a-zA-Z0-9])e|f) <=> e
            (?(?=[a-zA-Z0-9])e|c) <=> e

            (g(?=e)|(?<=g)e){2}
            Alt1 = g(?=e)
            Alt2 = (?<=g)e

            Er wird zwei Mal angewandt.

            Beim ersten Mal sind wir vor dem »G«, also RE|GEX. »g« frisst das »G«. Der Lookahead ist für »E« wahr, frisst es aber nicht. Alt1 ist insgesamt wahr.

            Beim zweiten Mal sind wir vor dem »E«, also REG|EX. Alt1 scheitert jämmerlich mit seinem »g«, also kommt Alt2 zum Zuge.
            Der Lookabehind ist für »G« wahr, frisst es aber nicht. »e« frisst das »E«. Alt2 ist insgesamt wahr.

            Ich denke der Rest des Gesamtmusters ist jetzt banal.

            Gruß Uwe

            1. Hallo

              [... viel ...]

              Sehr gut!

  4. gudn tach!

    Hallo, ich hab ein Rätsel für gemacht: Was matcht dieses Regex-Pattern (Perl Syntax)?

    eine anmerkung dazu:
    (?P<name>pattern) ist _nicht_ perl-syntax!

    perl meckert an so einer stelle
      Sequence (?P...) not recognized in regex [...]

    perl meckert ausserdem bei solchen wie [^$]

    $pattern = '/(?<=^).(?<![^r])(?=(?(?!.)d|(?P<a>e))).(g(?=(?(?=[a-zA-Z0-9])(?P=a)|f))|(?<![^g])(?(?=[a-zA-Z0-9])(?P=a)|c)){2}(?(?=[a-zA-Z0-9])x|y)(?![^$])/';

    in php4 funzt der ausdruck nicht und php5 habe ich hier nicht griffbereit, aber wenn (?P=a) einfach auf die referenz, die unter dem namen "a" gespeichert ist, zugreift und wenn (?![^$]) in php tatsaechlich bloss $ ist, dann ist die loesung einfach; und uebrigens auch eindeutig, d.h. der regexp matcht genau einen string. ich verrat ihn nicht, aber es ist wirklich sehr einfach.

    ich habe die meiste zeit damit verbracht, dieses verkackte (?P...) zu verstehen, bis ich spasseshalber mal ins php-manual reingeschaut habe. und selbst dort ist die erklaerung dazu unter aller sau.

    naja, egal. nettes raetsel jedenfalls.

    prost
    seth

    1. Hallo

      eine anmerkung dazu:
      (?P<name>pattern) ist _nicht_ perl-syntax!

      perl meckert an so einer stelle
        Sequence (?P...) not recognized in regex [...]

      perl meckert ausserdem bei solchen wie [^$]

      Sorry, dass hab ich nicht gewusst. PHP.net sagt zu preg_match, es nehme Pattern im Perl-Syntax an.

      Gruss

      1. gudn tach!

        ist _nicht_ perl-syntax!

        Sorry, dass hab ich nicht gewusst. PHP.net sagt zu preg_match, es nehme Pattern im Perl-Syntax an.

        stimmt nur fast. zwar laesst das php-manual anklingen, dass nicht alles gleich ist; dennoch ist die bezeichnung
        pcre einfach irrefuehrend.

        prost
        seth