e7: Regulärer Ausdruck gesucht: & in URL's umwandeln

Hi,

nach einer langen, langen Suche im Archiv und im Internet wende ich mich jetzt doch hier im Forum an euch. Und zwar geht es um folgendes: Ich arbeite gerade wieder an einer neuen Website, und diesmal will ich alles von Anfang an korrekt machen - sprich: XHTML Strict. Nur hab ich jetzt das folgende Problem: Das & in <a href="...">

Schon oft diskutiert, hier mal ein bisschen Archiv:
http://forum.de.selfhtml.org/archiv/2002/6/15717/#m87867
http://forum.de.selfhtml.org/archiv/2002/7/16619/#m92908

Nun bin ich also auf der Suche nach einem einfachen regulären Ausdruck für PHP (für eregi_replace oder so was), mit dem ich in einem Text (Inhalt der Seite, mittels OutputBuffering abgefangen) alle & innerhalb eines <a href=""> zu &amp; umwandeln kann... Leider verfüge ich nicht selbst über Kenntnisse von regulären Ausdrücken, ich wäre euch dafür für eine kurze Zeile dazu dankbar ;)

E7

  1. Hi,

    Nun bin ich also auf der Suche nach einem einfachen regulären Ausdruck für PHP (für eregi_replace oder so was), mit dem ich in einem Text (Inhalt der Seite, mittels OutputBuffering abgefangen) alle & innerhalb eines <a href=""> zu &amp; umwandeln kann...

    für die Umwandlung eines statischen Strings in einen anderen statischen String brauchst Du keine Regular Expressions, und für die Bedingung "innerhalb von" sind sie nicht geeignet. Du suchst also völlig falsch.

    Leider verfüge ich nicht selbst über Kenntnisse von regulären Ausdrücken,

    Du könntest ein RegExp-Gott sein, das würde Dir auch nicht helfen.

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Hi,

      für die Umwandlung eines statischen Strings in einen anderen statischen String brauchst Du keine Regular Expressions, und für die Bedingung "innerhalb von" sind sie nicht geeignet. Du suchst also völlig falsch.

      Du könntest ein RegExp-Gott sein, das würde Dir auch nicht helfen.

      Sprich: Das Vorhaben ist also unmöglich, und ich soll mir einen anderen Weg suchen?

      E7

      1. Hi,

        Sprich: Das Vorhaben ist also unmöglich, und ich soll mir einen anderen Weg suchen?

        wenn das Vorhaben auf Regular Expressions basiert: ja. Sofern der zu ersetzende Code noch keine Entities enthält, ist der andere Weg allerdings in höchstem Maße trivial.

        Cheatah

        --
        X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
        X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
        X-Will-Answer-Email: No
        X-Please-Search-Archive-First: Absolutely Yes
        1. Hallo,

          wenn das Vorhaben auf Regular Expressions basiert: ja. Sofern der zu ersetzende Code noch keine Entities enthält, ist der andere Weg allerdings in höchstem Maße trivial.

          Also manchmal muß ich mich schon wundern was hier für Statements und Tipps abgegeben werden. Vor allem dann wenn es 'alte Forumshasen' sind.

          Das Netz quilt doch wirklich über mit Lösungsbeispielen für solche Standardaufgaben wie mal eben eine HTML-Seite zu parsen und irgendetwas darin zu ändern.

          Aber vielleicht sollte man, wenn man eine qualifizierte Antwort ohne viel Tamtam drumherum haben möchte, nicht hier fragen?

          Hier findet man z.B. die Lösung inkl. Erklärung in ihrer Grundform, wie ich sie am Ende des Postings in leicht modifizierter Form auch mal einstelle.

          Und es würde mich wundern, wenn die FAQ der Newsgroup de.comp.lang.php hier nicht bekannt wäre. Im Gegenteil, ich denke, das die meisten (von den 'Forumshasen'), wenn sie etwas machen wollen und nicht genau wissen wie, dort schauen gehen, oder dort in der Vergangenheit nachgeschaut haben.

          Viele Grüße,
          Horst

          // Diese Funktion arbeitet eine ganze (gepufferte) HTML-Seite ab,
          // indem sie jeden a- area- und img-tag findet, die darin befindliche URL
          // gegebenenfalls von der Funktion rewrite_url() umschreiben laesst, die
          // umgeschriebene Seite in der Variablen $newpage sammelt und am Ende
          // als komplette Seite zurückgibt!

          function rewrite_page($page)
          {
           $a = array();
           $newpage = '';
           //              1          2        3          4            <5>           6           7
           $pattern = '=^(.*?)(<area|<a|<img)(.*?)(href=|src=)"|'"|'(>.*$|>.*?</a>.*$)=msi';
           while(preg_match($pattern, $page, $a))
           {
            if(count($a)>1)
            {
             $page = $a[7];
             $newpage .= $a[1].$a[2].$a[3].$a[4].'"'.rewrite_url($a[5]).'"'.$a[6];
            }
           }
           return $newpage.$page;
          }

          function rewrite_url($url)
          {
           $temp = explode('?',$url);
           if(!isset($temp[1]))
           {
            // kein Querystring in der URL
            return $url;
           }
           else
           {
            // es gibt einen Querystring und darin vorhandene &'s werden umgeschrieben
            return $temp[0].'?'.str_replace('&','&amp;',$temp[1]);
           }
          }

          1. Hallo,

            noch ein kleiner Nachtrag:

            die Funktion rewrite_url() habe ich vorhin nur so 'hingeschlufert', weil ich die in der Form nicht hatte. Heißt: ich nutze die rewrite_page() nicht, (oder nutzte bisher nicht, ;-)) um & in den URLs umzuschreiben.

            Da hätte ich dann wohl das Label '_ungetestet_' vergeben müßen.

            Deshalb hier ein kleiner Nachtrag:

            // neue rewrite_url() die evtl. vorhandene &amp;'s erkennt =:)
            function rewrite_url($url)
            {
             $temp = explode('?',$url);
             if(!isset($temp[1]))
             {
              // kein Querystring in der URL
              return $url;
             }
             else
             {
              // es gibt einen Querystring und darin vorhandene & werden umgeschrieben, &amp; aber nicht
              return $temp[0].'?'.preg_replace('/(&)(?!amp;)/','&amp;',$temp[1]);
             }
            }

            Viele Grüße,
            Horst

            1. Noch mal hallo,

              Hmm, ja, - man muß nicht unterscheiden zwischen & im Pfad einer URI und denen im Querystring. Keine Ahnung warum ich das gemacht habe (grübel).

              Man kann also die komplette $url in einer Zeile umschreiben.

              Evtl. bietet es sich trotzdem an dazu eine eigenständige Funktion anzulegen. Die kann man dann auch nutzen wenn schon einzelne URI-Strings zur Verfügung stehen. Anderenfalls kann man den Funktionsaufruf in der rewrite_page() durch preg_replace('/(&)(?!amp;)/','&amp;',$a[5]) ersetzen.

              // ganz neue rewrite_url() =:)
              function rewrite_url($url)
              {
                return preg_replace('/(&)(?!amp;)/','&amp;',$url);
              }

              Gruß,
              Horst

    2. für die Umwandlung eines statischen Strings in einen anderen statischen String brauchst Du keine Regular Expressions, und für die Bedingung "innerhalb von" sind sie nicht geeignet.

      Ähm, häh? Natürlich kann man mit regulären Ausdrücken den Inhalt von <a href="..."> herausbekommen. Auch, wenn noch andere Attribute im Tag stehen. Und mit dem e-Modifier kann mit diesem Inhalt alles angestellt werden, was PHP zulässt.

      Mathias

      1. Hi,

        Ähm, häh? Natürlich kann man mit regulären Ausdrücken den Inhalt von <a href="..."> herausbekommen.

        ich gehe davon aus, dass nicht nur dieses winzige Codeschnipselchen vorhanden ist. Regular Expressions sind _nicht_ geeignet, um Strukturen zu analysieren.

        Cheatah

        --
        X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
        X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
        X-Will-Answer-Email: No
        X-Please-Search-Archive-First: Absolutely Yes
        1. Hallo Cheatah,

          Ähm, häh? Natürlich kann man mit regulären Ausdrücken den Inhalt von <a href="...">
          herausbekommen.

          ich gehe davon aus, dass nicht nur dieses winzige Codeschnipselchen vorhanden ist.
          Regular Expressions sind _nicht_ geeignet, um Strukturen zu analysieren.

          Wenn sie wirklich regulaer waeren. Aber: sind sie nicht. Ein Beispiel, dass sie es nicht
          sind, ist das hier aus der perldoc:

          my $re;
          $re = qr~((?:(?>[^()]+)|(??{$re}))*)~x;

          Es matcht Klammer-Paare, und zwar in beliebiger Tiefe. Beispiel einer Anwendung:

          my $re;
          $re = qr~((?:(?>[^()]+)|(??{$re}))*)~x;

          die 'parens 1 not matching' unless '(a(b(c(d(e(f)g)h)i)j)k)' =~ $re;
          die 'parens 2 not matching' unless '(a(b(c(d(e(fg)hi)jk)' =~ $re;

          Grüße,
           CK

          --
          Willst du die Freuden dieser Welt geniessen, so musst du auch ihr Leid erdulden.
          http://wwwtech.de/
        2. ich gehe davon aus, dass nicht nur dieses winzige Codeschnipselchen vorhanden ist. Regular Expressions sind _nicht_ geeignet, um Strukturen zu analysieren.

          Es ist hier nicht notwendig, Strukturen zu analysieren, höchstens wünschenswert, weil (bzw. genau dann, wenn) sich gewisse Ausnahmen zwar mit regulären Ausdrücken mehr schlecht als recht abfangen lassen, deren Komplexität sich aber mit jeder Ausnahmebehandlung den Methoden eines echten Tokenizers annähert.

          Im Übrigen sind vermutlich alle Lösungen, die das Markup bei jedem Ausliefern durch Output Buffering verändern, unpassend. Korrekte Attributwerte sollten nicht erst nachträglich erzeugt werden. Selbst wenn man theoretisch geeignete Werkzeuge verwenden würde, also etwa XML-Parser, nützt es wenig, solange der Zweck des Unternehmens ist, nicht-wohlgeformtes Markup zu korrigieren (Dilemma).

          Das Problem liegt also woanders und kann auch nur dort effizient korrigiert werden. Die statischen Codeteile sollten fehlerfrei sein und bei der Generierung der dynamischen Teile muss ebenfalls darauf geachtet werden. Tidy nutzt z.B. einen fähigen Parser und korrigiert solche Entity-Fehler automatisch.

          Mathias

  2. Huhu e7

    mit look ahead geht es eigentlich ganz einfach, auch wenn
    das keine Performance Wunder vollbringen wird.

    $regexp = "/(&)(?![^>]+(<|$))/i";

    Hier mal ein vollständiges Beispiel
    <?php

    $test = <<<EOT

    &mdash; <a href="http://www.0815.net?a=12&b=12&c=13">Test GmbH &amp; Co KG </a>

    & bei Bildern &nbsp;

    <img src="thumbnail.php?x=12&y=400">

    & wieso soll das nicht gehen?

    EOT;

    $regexp = "/(&)(?![^>]+(<|$))/i";

    $new = preg_replace ($regexp, '&amp;', $test);

    echo $new;

    ?>

    Viele Grüße

    lulu

    --
    bythewaythewebsuxgoofflineandenjoytheday
    1. Hi,

      $regexp = "/(&)(?![^>]+(<|$))/i";

      Äh ja wo ist hier das a href zu sehen? Ich brauche das lediglich in href="..."

      & wieso soll das nicht gehen?

      Weil es kein gültiges HTML ist. Ein index.php?id=irgendwas&subid=nochwas geht nicht, da &subid= als Entidy behandelt werden müsste, und es leider bzw. zum Glück nicht existiert

      E7

  3. nach einer langen, langen Suche im Archiv und im Internet wende ich mich jetzt doch hier im Forum an euch. Und zwar geht es um folgendes: Ich arbeite gerade wieder an einer neuen Website, und diesmal will ich alles von Anfang an korrekt machen - sprich: XHTML Strict. Nur hab ich jetzt das folgende Problem: Das & in <a href="...">

    Problem = Spatz / Reguläre Ausdrücke = Kanone.

    Wie wäre es mit:

    $xmlurl = str_replace( '&', '&amp;', $url );

    Ist auch viel schneller als RegExp...

    imbt (at) compuserve (punkt) com

    1. Hallo zimt,

      Problem = Spatz / Reguläre Ausdrücke = Kanone.

      Wie wäre es mit:

      $xmlurl = str_replace( '&', '&amp;', $url );

      Ist auch viel schneller als RegExp...

      Das betrifft aber dann auch alle & ausserhalb von href="..." sowie alle bereits
      maskierten & innerhalb von URLs.

      Grüße,
       CK

      --
      Unsere Vorstellungen von der Ewigkeit sind genauso nuetlich wie die Mutmassungen eines Kuehkens ueber die Aussenwelt bevor es die Eierschale aufbricht.
      http://wwwtech.de/