Heizer: RegEx für URL

Guten Morgen

Ich bräuchte eine RegEx, mit der festzustellen ist, ob eine URL gültig ist, so wie hier im Forum.

So weit ich das verstanden habe, ist es in PHP ja möglich, sowohl PHP als auch Perl RegEx zu verwenden, ich habe auch etwas gefunden, aber irgendwie, naja, seht selbst:

http://www.foad.org/~abigail/Perl/url3.regex

Danke

Heizer

  1. Ich bräuchte eine RegEx, mit der festzustellen ist, ob eine URL gültig ist, so wie hier im Forum.

    Das ist schwierig. Für welches URI-Schema denn?

    So weit ich das verstanden habe, ist es in PHP ja möglich, sowohl PHP als auch Perl RegEx zu verwenden, ich habe auch etwas gefunden, aber irgendwie, naja, seht selbst:

    http://www.foad.org/~abigail/Perl/url3.regex

    Joa, und das bindest du nun in ein preg_match ein. Wo ist dein Problem?

    1. Hallo,

      Ich bräuchte eine RegEx, mit der festzustellen ist, ob eine URL gültig ist, so wie hier im Forum.

      Das ist schwierig. Für welches URI-Schema denn?

      ;) Ich glaube, er meinte HTTP, FTP, vielleicht mailto: und news:. Dafür würde möglicherweise http://www.dclp-faq.de/q/q-regexp-uri-klickbar.html ausreichen.

      So weit ich das verstanden habe, ist es in PHP ja möglich, sowohl PHP als auch Perl RegEx zu verwenden, ich habe auch etwas gefunden, aber irgendwie, naja, seht selbst:

      http://www.foad.org/~abigail/Perl/url3.regex

      Wow, das nenne ich krass.

      Joa, und das bindest du nun in ein preg_match ein. Wo ist dein Problem?

      Compilation failed: unrecognized character after (? at offset 4

      30

      Nee, ich glaube nicht, dass ich den Fehler suchen will.

      Mathias

      1. Hi,

        Nee, ich glaube nicht, dass ich den Fehler suchen will.

        ich helfe Dir: Er ist am Ende _jeder_ Zeile ;-)

        Cheatah

        P.S.: Die RegExp wurde nur der Lesbarkeit wegen umgebrochen. Korrekt ist sie nur dann, wenn die Umbrüche wieder entfernt werden und der Code somit in einer einzigen Zeile steht.

        1. Hi,

          Nee, ich glaube nicht, dass ich den Fehler suchen will.

          P.S.: Die RegExp wurde nur der Lesbarkeit wegen umgebrochen. Korrekt ist sie nur dann, wenn die Umbrüche wieder entfernt werden und der Code somit in einer einzigen Zeile steht.

          Tja, soll man dann diese RegExp verwenden? Wie sieht denn das mit der Performanze unter PHP aus?

          Heizer

          1. Hi,

            Tja, soll man dann diese RegExp verwenden?

            alle anderen, die technisch von dieser abweichen, haben den Nachteil, falsch zu sein. Diese RegExp hält sich an den Standard des RFC 1738, welcher noch immer internationale Gültigkeit besitzt und damit als einziges als richtig bezeichnet werden kann.

            Wie sieht denn das mit der Performanze unter PHP aus?

            Mach einen Benchmark-Test. Bedenke dabei, dass RegExp kompiliert werden, also nach erstmaliger Verwendung im Scriptverlauf hochperformant zur Verfügung stehen.

            Cheatah

            1. Hi,

              Tja, soll man dann diese RegExp verwenden?

              alle anderen, die technisch von dieser abweichen, haben den Nachteil, falsch zu sein. Diese RegExp hält sich an den Standard des RFC 1738, welcher noch immer internationale Gültigkeit besitzt und damit als einziges als richtig bezeichnet werden kann.

              Soweit, sogut, in einem Artikel im Archiv, den ich über deinen "prospero" Hinweis gefunden habe (bisher wußte ich nichtmal, was prospero ist) bewschreibst du ein Problem mit Tilden, die offiziell nicht in URI's vorkommen dürfen. Nachdem du sagst, diese RegExp sein die einzig richtige, gehe ich davon aus, daß Tilden nicht enthalten sind. Das ist eigentlich schade, dafür kenne ich dann doch zu viele Leute mit Tilden in der URI.
              http://forum.de.selfhtml.org/archiv/2000_3/t21614.htm#a110363

              Wie sieht denn das mit der Performanze unter PHP aus?

              Mach einen Benchmark-Test. Bedenke dabei, dass RegExp kompiliert werden, also nach erstmaliger Verwendung im Scriptverlauf hochperformant zur Verfügung stehen.

              Das heißt aber, daß sie bei jedem Aufruf der Datei selbst neu kompiliert werden muß, oder gibt es eine Möglichkeit, die kompilierte Version abzuspeichern?

              Danke

              Heizer

              1. Hi,

                Soweit, sogut, in einem Artikel im Archiv, den ich über deinen "prospero" Hinweis gefunden habe (bisher wußte ich nichtmal, was prospero ist) bewschreibst du ein Problem mit Tilden, die offiziell nicht in URI's vorkommen dürfen. Nachdem du sagst, diese RegExp sein die einzig richtige, gehe ich davon aus, daß Tilden nicht enthalten sind. Das ist eigentlich schade, dafür kenne ich dann doch zu viele Leute mit Tilden in der URI.

                ja, genau daher auch jener Artikel. Prinzipiell müsste die Tilde URL-kodiert werden (%7E? Weiß nicht mehr genau.), aber das passiert in der Praxis leider zu selten. Dass es trotzdem funktioniert, basiert auf hoher Fehlertoleranz aller betroffenen Systeme.

                Mach einen Benchmark-Test. Bedenke dabei, dass RegExp kompiliert werden, also nach erstmaliger Verwendung im Scriptverlauf hochperformant zur Verfügung stehen.
                Das heißt aber, daß sie bei jedem Aufruf der Datei selbst neu kompiliert werden muß, oder gibt es eine Möglichkeit, die kompilierte Version abzuspeichern?

                Soweit ich weiß nicht. Wie es beim Einsatz von mod_php aussieht, kann ich allerdings nicht beurteilen; ich vermute, hierbei bestehen Chancen. Ist PHP jedoch im CGI-Modus installiert, bedeutet das, dass das Script bei jedem Aufruf erneut in einen frisch gestarteten PHP-Interpreter geladen wird und somit kaum die Chance einer requestübergreifenden Kompilierung besteht.

                Du hast allerdings nicht mit spürbaren Performance-Einbußen zu rechnen; zumindest nicht, solange Du unter einer zählbaren Menge an Requests pro Sekunde bleibst.

                Cheatah

                1. Vielen Dank Cheatah, hast mir sehr geholfen

                  Heizer

        2. Hallo, Cheatah,

          Nee, ich glaube nicht, dass ich den Fehler suchen will.

          Die RegExp wurde nur der Lesbarkeit wegen umgebrochen.

          Sag bloß! ;) Ja, das ist mir durchaus aufgefallen.

          Korrekt ist sie nur dann, wenn die Umbrüche wieder entfernt werden und der Code somit in einer einzigen Zeile steht.

          <rechtfertigung>
          Deshalb habe die Zeilenumbrüche vor dem ersten Test entfernt. Daraufhin wurde ein Fehler ausgegeben, den ich mir absolut nicht erklären konnte, woraufhin ich einen Fehler beim Entfernen der Zeilenumbrüche vermutete. Daraufhin entfernte ich sie erneut, der Fehler blieb aber bestehen. Nun wechselte ich den Delimiter und immerhin änderte sich der Fehler *fg*. Erst als ich die RegExp wieder mit den Umbrüchen verwendete, wurde ein einigermaßen verständlicher Fehler ausgegeben, nämlich einer im Regulären Ausdruck selbst (siehe Posting).
          Naja, lange Rede, kurzer Sinn, gerade probierte ich es noch einmal (mit verschiedenen Delimitern) und es geht, grummel. Dabei hatte ich schon von Anfang an Delimiter benutzt, welche selbst nicht in der RegExp vorkamen.
          </rechtfertigung>

          Die Performance ist natürlich äußerst suboptimal[tm]. Nach 5000 Testdurchgängen bei einer einfachen HTTP-URL mit Query String (preg_match):

          lange RegExp: durchschnittlich 0.01552809 Sekunden
          kurze RegExp: durchschnittlich 0.00065359 Sekunden

          Die Messung beeinträchtigt natürlich das Resultat, aber die Tendenz ist offensichtlich. Selbst wenn die lange RegExp einmal kompiliert und danach schneller ausgeführt wird, wie du sagst, steht dies in keinem Vergleich zur kurzen RegExp:

          1. Test: 1:  0.03177 2:  0.00235
          2. Test: 1:  0.01850 2:  0.00054

          Manchmal braucht die erste RegExp beim ersten Ausführen auch 0,07 Sekunden und beim zweiten Ausführen 0,04 Sekunden.
          Ich weiß nicht, wie man innerhalb des Skriptes den Speicher von dem Regexp-Kompilat befreien kann, deswegen sind letztere Untersuchungen manuell durchgeführt worden. Aber die Zeit halbiert sich tatsächlich.

          Mathias

          1. Hi,

            Die RegExp wurde nur der Lesbarkeit wegen umgebrochen.
            Sag bloß! ;) Ja, das ist mir durchaus aufgefallen.

            sorry :-) Ist halt ein typischer Fehler, der fast automatisch auftritt, wenn jemand diese Variante der RegExp entdeckt...

            Die Performance ist natürlich äußerst suboptimal[tm]. Nach 5000 Testdurchgängen bei einer einfachen HTTP-URL mit Query String (preg_match):

            Japp, ungefähr sowas hatte ich erwartet. Jetzt gibt es insbesondere zwei Fragen, die Du Dir in jedem Anwendungsfall stellen solltest:

            1.) Wie wichtig ist es Dir, _alle_ korrekten URLs zu erkennen _und_ alle inkorrekten abzulehnen?
            2.) Wie oft (Frequenz und jeweils Menge) muss die Prüfung stattfinden?

            lange RegExp: durchschnittlich 0.01552809 Sekunden
            kurze RegExp: durchschnittlich 0.00065359 Sekunden

            Wenn es beispielsweise nicht mehr als ein oder zwei Prüfungen alle paar Sekunden gibt, ist ersteres nicht tragischer als letzteres - beides ist weder subjektiv (also dem User) noch objektiv (in Form von Performance-Einbußen, hoher Rechnerlast usw.) spürbar. Wirst Du jedoch n-fach pro Sekunde die Routine aufrufen müssen, ist die kurze RegExp oder eine verkürzte Variante der langen (z.B. reduziert auf nur ein oder zwei Protokolle) empfehlenswert. In dem Fall solltest Du Dir allerdings grundlegende organisatorische Gedanken darüber machen, wie Du das Gesamtsystem optimierst.

            Cheatah

      2. Nochmal guten Morgen und vielen Dank euch allen

        Heizer

  2. Guten Morgen.

    Warum für RegExps extra wo anders suchen? Im SelfRaum gibt's doch nichts was es nicht gibt. :)
    http://selfaktuell.teamone.de:81/tippstricks/programmiertechnik/email/index.html erklärt zwar das ganze für Mailadressen, denke aber, dass es sich mit etwas Geschick für URLs umbauen lässt.

    Grüße aus Würzburg
    Julian

    1. Hi,

      Warum für RegExps extra wo anders suchen? Im SelfRaum gibt's doch nichts was es nicht gibt. :)

      genau. Such mal im Archiv nach "prospero", da wirst Du so ziemlich die gleiche RegExp finden ;-)

      [...] erklärt zwar das ganze für Mailadressen, denke aber, dass es sich mit etwas Geschick für URLs umbauen lässt.

      Ähm, RFC 2822 und RFC 1738 sind ein _bisschen_ unterschiedlich. Geschick alleine wird da nicht ausreichen...

      Cheatah

      1. Hallo.

        genau. Such mal im Archiv nach "prospero", da wirst Du so ziemlich die gleiche RegExp finden ;-)

        selfsuche war heute morgen nicht erreichbar. Ansonsten hätt's auch einen Verweis aufs Archiv gegeben.

        Ähm, RFC 2822 und RFC 1738 sind ein _bisschen_ unterschiedlich. Geschick alleine wird da nicht ausreichen...

        Naja, ein Check für den Normalanweder kann man sich find ich schon draus basteln. Habe mir auch einen Check mal zusammengeschustert, wenngleich nicht sooo perfekt, aber die meisten URLs schluckt er doch ohne Gemecker.

        Grüße aus Würzburg
        Julian

        1. Hi,

          Ähm, RFC 2822 und RFC 1738 sind ein _bisschen_ unterschiedlich. Geschick alleine wird da nicht ausreichen...
          Naja, ein Check für den Normalanweder kann man sich find ich schon draus basteln. Habe mir auch einen Check mal zusammengeschustert, wenngleich nicht sooo perfekt, aber die meisten URLs schluckt er doch ohne Gemecker.

          wenn nicht alle korrekten URLs akzeptiert werden, mag das noch in Ordnung sein. Werden jedoch nicht alle _in_korrekten URLs _nicht_ akzeptiert, so ist das ein Problem.

          Cheatah