Onkel Schnitzel: Unknown modifier '|'

Hallo,

ich versuche mich gerade an Regulären Ausdrücken. Ich habe jetzt versucht, eine Funktion zu schreiben, die entweder die Zeichenfolge '&lang=en' oder '?lang=en' aus einer Zeichenkette entfernt, wenn sie vorkommt.

$uri = preg_replace("(&lang=en)|(/?lang=en)","",$uri);

Jetzt meckert der Parser herum "Unknown modifier '|'" . Wie (mit welcher Taste) schreibt man denn diesen oder-Strich?

Danke..

  1. $uri = preg_replace("(&lang=en)|(/?lang=en)","",$uri);

    Jetzt meckert der Parser herum "Unknown modifier '|'" . Wie (mit welcher Taste) schreibt man denn diesen oder-Strich?

    Ich möchte glatt behaupten, dass er nicht über den senkrechten Strich meckert, sondern darüber, dass du

    • das Fragezeichen mit einem Schräg- statt einem Rückstrich maskiert hast
    • dein Muster nicht in begrenzende Zeichen verpackt hast (üblicherweise Schrägstriche, es geht aber auch jedes andere Zeichen)

    Probiere doch mal (alles hier nicht notwendige, einschließlich der doppelten Anführungzeichen habe ich weggelassen):

    /(&lang=en)|(?lang=en)/

    Kürzer sollte sich deine Aufgabe übrigens so erledigen lassen:

    /(&|?)lang=en/

    Und da du eine ganze URI zu prüfen scheinst, müsste etwas in dieser Art exakter sein:

    /?(.+&|)lang=en(&.+|)$/

    1. Ich möchte glatt behaupten, dass er nicht über den senkrechten Strich meckert, sondern darüber, dass du

      • das Fragezeichen mit einem Schräg- statt einem Rückstrich maskiert hast

      Hm ja, schusselig...

      • dein Muster nicht in begrenzende Zeichen verpackt hast (üblicherweise Schrägstriche, es geht aber auch jedes andere Zeichen)

      Ich dachte die Anführungszeichen wären diese Begrenzer.

      Probiere doch mal (alles hier nicht notwendige, einschließlich der doppelten Anführungzeichen habe ich weggelassen):

      /(&lang=en)|(?lang=en)/

      Ich habs jetzt mal so versucht:
      $uri = preg_replace(/(&lang=en)|(?lang=en)/,"",$uri);

      und bekomme jetzt das:
      Parse error: syntax error, unexpected '/', expecting ')' in /home/www/Mecon/index.php on line 24

      Kannst du mir nochmal nen Tip geben? Vielen Dank schonmal soweit!

      1. Moin!

        • dein Muster nicht in begrenzende Zeichen verpackt hast (üblicherweise Schrägstriche, es geht aber auch jedes andere Zeichen)

        Ich dachte die Anführungszeichen wären diese Begrenzer.

        In PHP sieht die Sache anders aus, als in Perl.

        In Perl schreibst du die regulären Ausdrücke "nackt" in die Programmzeile.
        In PHP muß der reguläre Ausdruck, weil er ein String ist, in Anführungszeichen rein. Aber da er ein Regex-Kommandostring ist (genau wie z.B. ein SQL-Querystring), muß er natürlich die Regex-Kommandozeichen enthalten, also die Regex-Begrenzer (üblicherweise Schrägstriche).

        Die Problematik zum korrekten Escapen von Escapes hatte ich schon Gonzo gepostet.

        - Sven Rautenberg

        --
        "Love your nation - respect the others."
        1. Hallo zusammen,

          Die Problematik zum korrekten Escapen von Escapes hatte ich schon Gonzo gepostet.

          Eigentlich sind die Besipiele im PHP-Manual ganz einleuchtend zusammengestellt.
          http://de.php.net/manual/de/function.preg-replace.php

          LG
          Chris©

        2. Ich habs jetzt zur Hälfte hinbekommen. Wenn '?lang=en' vorkommt, entfernt er mir das. Nur mit '&lang=en' klappts nicht. Ich hab schon alles mögliche escaped, aber das hat nichts gebracht.

          Hat jemand noch nen Tip, wo's hakt?
          $uri = preg_replace('/(&lang=en)|(\?lang=en)/','',$uri);

          Besten Dank,
          Onkel Schnitzel

          1. Ich habs jetzt zur Hälfte hinbekommen. Wenn '?lang=en' vorkommt, entfernt er mir das. Nur mit '&lang=en' klappts nicht. Ich hab schon alles mögliche escaped, aber das hat nichts gebracht.

            Hat jemand noch nen Tip, wo's hakt?
            $uri = preg_replace('/(&lang=en)|(\?lang=en)/','',$uri);

            Ok, hat sich erledigt. '&' statt '&' war die Lösung.

    2. Moin!

      Probiere doch mal (alles hier nicht notwendige, einschließlich der doppelten Anführungzeichen habe ich weggelassen):

      /(&lang=en)|(?lang=en)/

      Kürzer sollte sich deine Aufgabe übrigens so erledigen lassen:

      /(&|?)lang=en/

      Deine regulären Ausdrücke sind korrekt.

      Die spannende Aufgabe ist jetzt allerdings, diese korrekt durch den PHP-Stringparser durchzukriegen. Denn wenn da Anführungszeichen drumherum kommen, dann müssen ja diverse Zeichen escaped werden, um unverändert im String zu landen.

      Der Klassiker: Die Escape-Kombination für den Backslash ist \. Wenn man das vergißt, kriegt der Stringparser nicht "\?" zu sehen und macht daraus "?", sondern er sieht "?" (ein sinnlos escapetes Fragezeichen), und macht daraus "?" - und das ist nicht, was man im Regex haben will, auch wenn es eventuell glücklicherweise hier als literales Fragezeichen interpretiert wird, weil es an der Position direkt hinter der öffnenden runden Klammer seine Sonderbedeutung nicht haben kann.

      - Sven Rautenberg

      --
      "Love your nation - respect the others."
      1. /(&|?)lang=en/

        Die spannende Aufgabe ist jetzt allerdings, diese korrekt durch den PHP-Stringparser durchzukriegen. Denn wenn da Anführungszeichen drumherum kommen, dann müssen ja diverse Zeichen escaped werden, um unverändert im String zu landen.

        Nein (aber diese Feinheit hätte ich natürlich dazuschreiben können).

        1. /(&|?)lang=en/

          Die spannende Aufgabe ist jetzt allerdings, diese korrekt durch den PHP-Stringparser durchzukriegen. Denn wenn da Anführungszeichen drumherum kommen, dann müssen ja diverse Zeichen escaped werden, um unverändert im String zu landen.

          Nein (aber diese Feinheit hätte ich natürlich dazuschreiben können).

          Streiche "können", schreibe "müssen". Ich hatte explizit erwähnt, "doppelte Anführungszeichen" weggelassen zu haben, das bezog sich aber auf die dem Onkel  seine von ihn verwendete.

          Ich benutze unter PHP überwiegend einfache Anführungszeichen, hauptsächlich, weil ich im HTML-Code doppelte sehen möchte (was letztlich aber ja Jacke wie Hose ist …).

        2. Moin!

          /(&|?)lang=en/

          Die spannende Aufgabe ist jetzt allerdings, diese korrekt durch den PHP-Stringparser durchzukriegen. Denn wenn da Anführungszeichen drumherum kommen, dann müssen ja diverse Zeichen escaped werden, um unverändert im String zu landen.

          Nein (aber diese Feinheit hätte ich natürlich dazuschreiben können).

          Ich halte es für keine so gute Idee, den eingebauten Fehlerkorrekturmechanismus zu nutzen, um Backslashes einzusparen.

          ' ist in einfachen Anführungszeichen der Escape-Code für ein einfaches Anführungszeichen.
          \ ist der Escape-Code für einen einzelnen Backslash.
          \x alles andere mit Backslash davor wird als \x ausgegeben.

          Da denkt man sich dann: Oh prima, \x ist 1:1 ausgegeben, dann mach ich mal eben \x draus für zwei Backslashes. Und nichts passiert.

          - Sven Rautenberg

          --
          "Love your nation - respect the others."
          1. Nein

            Ich halte es für keine so gute Idee, den eingebauten Fehlerkorrekturmechanismus zu nutzen, um Backslashes einzusparen.

            Da denkt man sich dann: Oh prima, \x ist 1:1 ausgegeben, dann mach ich mal eben \x draus für zwei Backslashes. Und nichts passiert.

            Es hat mit Fehlerkorrektur nicht viel zu tun, wenn die Spezifikation besagt, dass nur eine Maske für das einfache Anführungszeichen und den Rückstrich existiert, und dies dann auch so gehandhabt wird. Zu bemängeln wäre eher, dass in der Anleitung \ nicht erwähnt wird, sondern nur die Maske für den Fall ' in der Ausgabe, der dann als \' im Code erscheinen muss.

            Dabei handelt es sich bestenfalls um ein Problem einer dusseligen Spezifikation. Aber das ist ja normal bei PHP - von schlunzigen Fricklern geschrieben, für schlunzige Frickler gemacht … ;->

          2. gudn tach!

            Ich halte es für keine so gute Idee, den eingebauten Fehlerkorrekturmechanismus zu nutzen, um Backslashes einzusparen.

            ich wuerde das wie auch Gonzo nicht als eingebauten fehlerkorrekturmechanismus bezeichnen, sondern als intelligente spezifikation.
            setzt man einen string in einfache anfuehrungszeichen, muessen ja nur weitere einfache anfuehrungszeichen und backslashes vor einfachen anfuehrungszeichen maskiert werden. ein zusaetzliches maskieren waere redundant (aber nicht verboten). und dass redundanz fakultativ ist, halte ich fuer vernuenftig, ebenso wie z.b. bei regexps:
               /(foo)/
            matcht "(foo)", da die zweite klammer nicht maskiert werden muss.

            ' ist in einfachen Anführungszeichen der Escape-Code für ein einfaches Anführungszeichen.
            \ ist der Escape-Code für einen einzelnen Backslash.
            \x alles andere mit Backslash davor wird als \x ausgegeben.

            Da denkt man sich dann: Oh prima, \x ist 1:1 ausgegeben, dann mach ich mal eben \x draus für zwei Backslashes. Und nichts passiert.

            warum sollte man sich das denken? das macht keinen sinn, sondern verstoesst gegen die zweite genannte regel.

            prost
            seth