[REGEX] Sehr gefräßiger Regulärer Ausdruck - bitte um Hilfe

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [REGEX] Sehr gefräßiger Regulärer Ausdruck - bitte um Hilfe

    Hallo,

    ich versuche anhand des folgenden Patterns ALLE Link sin einem größeren HTML-Quelltext zu finden:

    PHP-Code:
    $pattern "!(<a.+?href=\"(.+?)\"(.*?)>(.+?)</a>)|(<a.+?href='(.+?)'(.*?)>(.+?)</a>)|(<a.+?href=(.+?) (.*?)>(.+?)</a>)!imsU" 
    Ich wende das Pattern mit der Funktion preg_match_all() an. Leider ist mein Ausdruck sehr gefräßig und schluckt nach dem "</a>" Tag fleißig weiter den nachfolgenden Text bis er irgendwann wieder auf einen </a> Tag trifft das als Ende des Patterns interpretiert wird. Danach geht das Spielchen mit dem nächsten Link von vorne los.

    Ich habe den U Modifier eingesetzt um die Gefräßigkeit zu unterbinden, jedoch scheint der keine Wirkung zu zeigen. Außerdem habe ich nach den . und + Metazeichen ? eingefügt - hilft aber auch nicht. Bin am Ende mit meinem Latein und bitte um Hilfe.

    thx geordi

  • #2
    entweder U oder ?

    die beiden heben sich in ihrer wirkung auf, sollte aber auch in der doku stehen
    Original geschrieben von http://de2.php.net/manual/de/referen....modifiers.php
    U (PCRE_UNGREEDY)

    Dieser Modifikator kehrt die Gier von Quantifikatoren um, sodass sie standardmäßig nicht gierig sind, aber gierig werden, wenn ihnen ein "?" folgt. Das ist nicht mit Perl kompatibel. Es kann auch innerhalb des Suchmusters mit dem Modifikator (?U) gesetzt werden.
    Ich denke, also bin ich. - Einige sind trotzdem...

    Kommentar


    • #3
      !<a\s.*\s?href="([^"]*)"!Usi
      reicht.

      Oder willst du auch noch wissen, was für ein Text verlinkt ist?
      mein Sport: mein Frühstück: meine Arbeit:

      Sämtliche Code-Schnipsel sind im Allgemeinen nicht getestet und werden ohne Gewähr auf Fehlerfreiheit und Korrektheit gepostet.

      Kommentar


      • #4
        ja aber dieser Ausdruck trifft nur auf solche links zu:

        <a href="/blabla/index.php" target="_self">test</a>

        jedoch nicht auf:

        <a href='/blabla/index.php' target="_self">test</a>

        oder gar:

        <a href=/blabla/index.php target="_self">test</a>

        richtig?

        Kommentar


        • #5
          ich habe mein Pattern nun auf folgendes abgeändert:

          PHP-Code:
          $pattern "!(<a.+?href=[\"(.+?)\"|'(.+?)']?(.*?)>.+?</a>)!ims"
          das sollte doch auf alle Links matchen die es gibt, d.h.

          .... href="lala.php" ....
          .... href='lala.php' ....
          .... href=lala.php ....

          achso ja ich brauche auch den text zwischen den <a> tags


          was meint ihr? haut das hin?

          Kommentar


          • #6
            Was drückt man eigentlich hiermit aus ... ?

            (.*?)

            oder hiermit .... ?

            (.+?)
            carpe noctem

            [color=blue]Bitte keine Fragen per EMail ... im Forum haben alle was davon ... und ich beantworte EMail-Fragen von Foren-Mitgliedern in der Regel eh nicht![/color]
            [color=red]Hinweis: Ich bin weder Mitglied noch Angestellter von ebiz-consult! Alles was ich hier von mir gebe tue ich in eigener Verantwortung![/color]

            Kommentar


            • #7
              http://www.weitz.de/regex-coach/

              teste den mal damit ...
              ist für windows ein programm mit dem man regex testen kann ...
              nette optionen ...
              und nen kleines tutorial gibts auch auf der seite

              Kommentar


              • #8
                .*?

                . => steht für jedes beliebige Zeichen
                * => steht für keine oder mehrere Wiederholungen
                ? => unterbindet die Gefräßigkeit des Reg. Ausdrucks


                .+?

                . => steht für jedes beliebige Zeichen
                + => steht für mindestens eine oder mehrere Wiederholungen
                ? => unterbindet die Gefräßigkeit des Reg. Ausdrucks


                Beispiel:
                <ahref="index.php"> würde mit .*? einen Match liefern, was aber nicht gewollt ist, denn das ist syntaktisch falscher HTML code, deswegen .+?
                dies trifft dann nur auf
                <a href="index.php"> zu

                Kommentar


                • #9
                  Original geschrieben von geordi
                  <ahref="index.php"> würde mit .*? einen Match liefern, was aber nicht gewollt ist, denn das ist syntaktisch falscher HTML code
                  Das passiert allerdings auch nur, wenn man nicht nach dem richtigen sucht ... wenn man nach "Leerzeichen" sucht ... nimmt man im Normalfall \s ... und sucht nicht einfach nach irgendwas ... !
                  Sucht man nach 'nem Parameterwert, sucht man eben auch nicht nach irgendwas ... sondern entweder nach den dort erlaubten Zeichen ... oder ... wie in Titus' Beispiel nach den nicht nicht erlaubten Zeichen ... !
                  carpe noctem

                  [color=blue]Bitte keine Fragen per EMail ... im Forum haben alle was davon ... und ich beantworte EMail-Fragen von Foren-Mitgliedern in der Regel eh nicht![/color]
                  [color=red]Hinweis: Ich bin weder Mitglied noch Angestellter von ebiz-consult! Alles was ich hier von mir gebe tue ich in eigener Verantwortung![/color]

                  Kommentar


                  • #10
                    Das passiert allerdings auch nur, wenn man nicht nach dem richtigen sucht ... wenn man nach "Leerzeichen" sucht ... nimmt man im Normalfall \s ... und sucht nicht einfach nach irgendwas ... !
                    ich suche deshalb nach irgendwas da es auch solche links gibt:

                    <a target="_self" href="bla.php"> ...

                    man muss einen link nicht immer so definieren: <a href="" target=""> ...


                    Hier meine fertigen Patterns für Links und Bilder, falls jemand mal das gleiche Problem wie ich haben sollte:

                    PHP-Code:
                    $HYPERLINK_PATTERN "!<a\\s.*\\s?href=\"([^\"]*)\"|<a\\s.*\\s?href='([^']*)'|<a\\s.*\\s?href=([^[:space:]]*)!Usi";

                    $IMAGE_PATTERN "!<img\\s.*\\s?src=\"([^\"]*)\"|<img\\s.*\\s?src='([^']*)'|<img\\s.*\\s?src=([^[:space:]]*)!Usi"
                    thx @ titus & mrhappiness ich habt mich auf den richtigen Weg geführt
                    Zuletzt geändert von geordi; 01.12.2004, 11:40.

                    Kommentar


                    • #11
                      noch ne Idee: wenn das ? /U umdreht, kann man auf * ausweichen:
                      !\<a\s([^>]*\s)*href="([^"]*)"(\s[^>]*)*>(.*)</a>!Usi

                      $2 = href
                      $4 = Link-Text
                      Zuletzt geändert von Titus; 01.12.2004, 14:39.
                      mein Sport: mein Frühstück: meine Arbeit:

                      Sämtliche Code-Schnipsel sind im Allgemeinen nicht getestet und werden ohne Gewähr auf Fehlerfreiheit und Korrektheit gepostet.

                      Kommentar


                      • #12
                        Das ist noch besser Titus!

                        habe nämlich festgestellt das meine Pattern die ich gestern geposted habe einen Fehler hatten, hier die neuen.

                        PHP-Code:
                        $HYPERLINK_PATTERN "!<a\\s[^>]*\\s*href=\\"([^\\"]*)\\"\\s[^>]*>|<a\\s[^>]*\\s*href='([^']*)'\\s[^>]*>|<a\\s[^>]*\\s*href=([^\\s]*)\\s[^>]*>!Usi"

                        $IMAGE_PATTERN = "!<img\\s[^>]*\\s*src=\\"([^\\"]*)\\"\\s[^>]*>|<img\\s[^>]*\\s*src='
                        ([^']*)'\\s[^>]*>|<img\\s[^>]*\\s*src=([^\\s]*)\\s[^>]*>!Usi"; 
                        Anmerkung: Diese beiden Pattern liefern einem mit preg_match_all() alle Urls innerhalb von HREF und SRC. Wenn ihr mehr wollt, z.B. das Target oder den Text zwischen den <a></a> Tags dann orientiert euch an Titus Beispiel oben und erweitert dieses für HREF oder SRC urls die mit ' oder einen space eingeschlossen sind. Hoffe das erspart jemandem Arbeit (sitze seit 3 Tagen daran...)

                        Wiederrum Danke für die Anregungen

                        Kommentar


                        • #13
                          Wer mehr als ein Attribut sucht, sollte eher erst das gesamte Tag mit einem preg_match_all ermitteln : '%<a(\s[^>]*)*>%'
                          und in einer folgenden Schleife über alle Matches die einzelnen Attribute aus jedem Tag filtern: '%(?<=\s)(\w+)=("?)([^"]*)\\2%'
                          PHP-Code:
                          preg_match_all('%<a(\s[^>]*)>(.*)</a>%U'$text$aPREG_SET_ORDER);
                          foreach(
                          $a as $x)
                          {
                            
                          preg_match_all('%(?<=\s)(\w+)=("?)([^"]*)\\2%'$x[1], $bPREG_SET_ORDER);
                            echo 
                          '<hr>a:<br>';
                            foreach(
                          $b as $y) echo '&nbsp;&nbsp;'$y[1], '='$y[3], '<br>';
                            echo 
                          'text = 'htmlentities($x[2]);

                          Das (w+) im zweiten Ausdruck kann natürlich auch durch eine Liste der gesuchten Attribute ersetzt werden, z.B. (href|title|target). Dann werden die anderen Attribute ignoriert.
                          mein Sport: mein Frühstück: meine Arbeit:

                          Sämtliche Code-Schnipsel sind im Allgemeinen nicht getestet und werden ohne Gewähr auf Fehlerfreiheit und Korrektheit gepostet.

                          Kommentar

                          Lädt...
                          X