Matthias: Minuszeichen in Regulärem Ausdruck escapen

Hallo zusammen,

kann mir jemand sagen, wie ich innerhalb eines Regulären Ausdrucks ein Minuszeichen (-) escape?

Ich habe folgenden Ausdruck und leider auch nicht viel Ahnung:
ereg_replace ("^(.*)(/)([A-Z|a-z|0-9|-|_]+)(/)$", "\3", $VAR)
Wobei das - nicht als Zeichen interpretiert wird, weil es als Sonderzeichen einen Bereich definiert, z.B. [A-Z].

Wenn ich jetzt aber den Backslah als Escape-Zeichen nutze, rüht sich immer noch nichts:
ereg_replace ("^(.*)(/)([A-Z|a-z|0-9|-|_]+)(/)$", "\3", $VAR)
passt nicht auf "Zeichen/Zeichen01-Zeichen02/". Mit einem Punkt ([A-Z|a-z|0-9|.|_]+) funktioniert es allerdings genauso wie gewünscht.

Wie wird ein Minus in einem Regulären Ausdruck auch als ein solches interpretiert?

Danke,
Matthias

  1. Hi,

    kann mir jemand sagen, wie ich innerhalb eines Regulären Ausdrucks ein Minuszeichen (-) escape?

    genau wie jedes andere: mit dem Backslash.

    ereg_replace ("^(.*)(/)([A-Z|a-z|0-9|-|_]+)(/)$", "\3", $VAR)

    Warum definierst Du in Deiner Zeichenklasse das Pipe-Zeichen vier mal? "[A-Za-z0-9-_|]" würde vollkommen reichen.

    Wobei das - nicht als Zeichen interpretiert wird, weil es als Sonderzeichen einen Bereich definiert, z.B. [A-Z].

    Ja, in diesem Fall "alles von '|' bis '|'".

    ereg_replace ("^(.*)(/)([A-Z|a-z|0-9|-|_]+)(/)$", "\3", $VAR)

    Das Problem ist, dass der String erst noch einer anderen (internen) Funktion übergeben wird, wobei Backslashes innerhalb der Quotes aufgelöst werden - anders könntest Du z.B. hier kein Doublequote als Zeichen übergeben. Willst Du, dass ein Backslash am anderen Ende ankommt, musst Du diesen escapen.

    Wie wird ein Minus in einem Regulären Ausdruck auch als ein solches interpretiert?

    Ja; außer in einer Zeichenklasse; außer er steht dort ganz am Ende.

    Cheatah

    1. Warum definierst Du in Deiner Zeichenklasse das Pipe-Zeichen vier mal? "[A-Za-z0-9-_|]" würde vollkommen reichen.

      Weil ich doch ahnungslos bin ;-) Danke für den Tipp.
      Funktioniert auch, bis auf die Sache mit dem Minus.
      Wie es scheint habe ich den Rest, den Du erklärt hast, nicht komplett durchblickt. Denn mit dem Minus weitergeholfen hat es mir nicht. Funktioniert "[A-Za-z0-9-_|]" bei dir einwandfrei?

      Wie wird ein Minus in einem Regulären Ausdruck auch als ein solches interpretiert?
      Ja; außer in einer Zeichenklasse; außer er steht dort ganz am Ende.

      Was heisst denn das? Wer ist "er"? Der RegEx? Bleibt die Ausage inhaltlich korrekt, wenn ich sie so umformuliere: "Ein Minus wird interpetiert. Innerhalb einer Zeichenmenge allerdings nicht - es sei denn es steht dort ganz am Ende." Verstehnix!

      1. Hoi, <-- sowas ist 'ne Begruessung,

        Warum definierst Du in Deiner Zeichenklasse das Pipe-Zeichen vier
        mal? "[A-Za-z0-9-_|]" würde vollkommen reichen.

        Weil ich doch ahnungslos bin ;-) Danke für den Tipp.
        Funktioniert auch, bis auf die Sache mit dem Minus.
        Wie es scheint habe ich den Rest, den Du erklärt hast, nicht
        komplett durchblickt. Denn mit dem Minus weitergeholfen hat es mir
        nicht. Funktioniert "[A-Za-z0-9-_|]" bei dir einwandfrei?

        Da du ja offensichtlich PHP benutzt, solltest du dir bewusst werden,
        dass das "-" als "-" an die RegEx-Maschine kommt. Du muesstest also
        "\-" schreiben, daraus wuerde naemlich "-".

        Wie wird ein Minus in einem Regulären Ausdruck auch als ein
        solches interpretiert?
        Ja; außer in einer Zeichenklasse; außer er steht dort ganz am
        Ende.
        Was heisst denn das?

        Das ein '-' sowohl am Ende einer Zeichenklasse (die erkennt man
        dadurch, dass sie von [] umschlossen sind) als auch ausserhalb einer
        Zeichenklasse als solches erkannt wird. Innerhalb der Zeichenklasse
        musst du es maskieren.

        Wer ist "er"? Der RegEx?

        Nein, der Bindestrich.

        Gruesse,
         CK

        1. Hoi Christian,

          Da du ja offensichtlich PHP benutzt, solltest du dir bewusst werden,
          dass das "-" als "-" an die RegEx-Maschine kommt. Du muesstest also
          "\-" schreiben, daraus wuerde naemlich "-".

          Das hatte ich schon ausprobiert - und auf deinen Rat hin auch gleich nochmal getestet, aber es hilft nicht! Noch eine Idee, was ich falsch mache? Liegt es vielleicht daran, dass ich "ereg" statt "preg" benutze? Ich glaube ich ersetze "^(.*)(/)([A-Za-z0-9\-_|]+)(/)([^/]*)$" einfach durch "^(.*)(/)([^/]+)(/)([^/]*)$", das müsste für meine Zwecke ausreichen. Auch wenn mich jetzt brennend interessiert, woran das mit dem Bindestrich hapert.

          Danke für die Hilfe,
          Matthias

          1. Hi,

            "er" war übrigens ein Tippfehler und hätte "es" für "das Minuszeichen" heißen sollen. Sorry für die Verwirrung.

            Das hatte ich schon ausprobiert - und auf deinen Rat hin auch gleich nochmal getestet, aber es hilft nicht!

            Mit welchen Tests hast Du das bei welchen Ergebnissen ermittelt?

            Liegt es vielleicht daran, dass ich "ereg" statt "preg" benutze?

            Die preg sind "Perl style". Ich muss zugeben, dass ich mit dieser Art der RegExp die meiste Erfahrung habe und nicht genau weiß, ob es bei ereg anders lauten müsste - normalerweise aber nicht. Wenn nichts anderweitiges dagegenspricht, solltest Du preg verwenden; soweit ich weiß ist dies auch eine allgemeine Empfehlung von PHP-Experten in Bezug auf die Performance.

            "^(.*)(/)([A-Za-z0-9\-_|]+)(/)([^/]*)$"

            Btw: Ich vermute mal, das "|" möchtest Du da nicht wirklich drin haben :-) Außerhalb einer Zeichenklasse steht es für "oder", innerhalb einer Zeichenklasse ist es einfach das Zeichen, ohne besondere Bedeutung.

            einfach durch "^(.*)(/)([^/]+)(/)([^/]*)$", das müsste für meine Zwecke ausreichen.

            Das kannst natürlich nur Du wissen. Aus Sicherheitsgründen solltest Du aber bei der Whitelist ("[xyz]") statt der Blacklist ("[^xyz]") bleiben; mindestens dann, wenn der überprüfte String in irgendeiner Form vom User kommen könnte (auch indirekt).

            Auch wenn mich jetzt brennend interessiert, woran das mit dem Bindestrich hapert.

            Möglicherweise an Deiner Interpretation ;-) Es ist leicht möglich, durch nicht optimale Testfälle einen "falschen Fehler" zu sehen.

            Cheatah