besonderer preg_match_all fall

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

  • besonderer preg_match_all fall

    hi, ich habe also eine Array($inhalt) in dem sind verschiedene Buchstaben (A-H) enthalten.

    <td>A</td>
    <td>B</td>
    <td>C</td>
    <td>D</td>
    <td>E</td>
    <td>F</td>
    <td>G</td>
    <td>H</td>

    Ausgehend vom "D"-td-containern(dort wo der Buchstabe "D" hereingeschrieben wurde)sollen 2 Container vor und nach dem "D"-td-containern die Inhalte ausgelesen werden.
    Also der "B"-td-containern und der "F"-td-containern.
    Die Inhalte lauten also "B" und "D" die ausgegeben werden sollen.

    Nur leider weiß ich gar nicht wie man das bewerkstelligen kann...
    Das scheint für evtl. Außenstehende nicht sinnvoll zu sein, aber es wär schön wenn man mir trotzdem helfen könnnte.

    preg_match_all(),$inhalt,$muster);

  • #2
    Hallo,

    mit Regulären Ausdrücken kommst du da nur sehr umständlich zum Ziel. Am besten macht man sowas mit XPath und DOM (z. B. $node->previousSibling->previousSibling)

    Gruß,

    Anja
    [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
    Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
    Super, danke!
    [/COLOR]

    Kommentar


    • #3
      plz remove..
      Zuletzt geändert von xManUx; 06.09.2009, 22:26.

      Es kommt nicht darauf an, mit dem Kopf durch den Monitor zu rennen,
      sondern mit den Augen das Manual zu lesen.

      Kommentar


      • #4
        Was hast Du denn vor? Du könntst zb so vorgehen:

        $inhalt = '<td>A</td>
        <td>B</td>
        <td>C</td>
        <td>D</td>
        <td>E</td>
        <td>F</td>
        <td>G</td>
        <td>H</td>';


        $search = 'D';
        $regEx = '~<(td)>(?<content>\w+)</\1>~Uis';
        preg_match_all($regEx, $inhalt, $result, PREG_SET_ORDER);
        for($i=0,$max = count($result); $i < $max; $i++) {
        if($result[$i]['content'] == $search) {
        echo '1. '.$result[$i-2]['content'].'<br/>';
        echo '2. '.$result[$i-1]['content'].'<br/>';
        echo 'Ausgehend von '.$search.'<br/>';
        echo '3. '.$result[$i+1]['content'].'<br/>';
        echo '4. '.$result[$i+2]['content'].'<br/>';
        }
        }

        Ergebnis:
        1. B
        2. C
        Ausgehend von D
        3. E
        4. F

        Es kommt nicht darauf an, mit dem Kopf durch den Monitor zu rennen,
        sondern mit den Augen das Manual zu lesen.

        Kommentar


        • #5
          Zitat von benutzer_michi Beitrag anzeigen
          hi, ich habe also eine Array($inhalt) in dem sind verschiedene Buchstaben (A-H) enthalten.

          <td>A</td>
          <td>B</td>
          <td>C</td>
          <td>D</td>
          <td>E</td>
          <td>F</td>
          <td>G</td>
          <td>H</td>

          Ausgehend vom "D"-td-containern(dort wo der Buchstabe "D" hereingeschrieben wurde)sollen 2 Container vor und nach dem "D"-td-containern die Inhalte ausgelesen werden.
          Also der "B"-td-containern und der "F"-td-containern.
          Die Inhalte lauten also "B" und "D" die ausgegeben werden sollen.
          PHP-Code:
          preg_match_all('/<td>(?:B|D)</td>/'$src$treffer); 
          Das Ergebnis kannst du im Array $treffer bewundern.

          Unter der Annahme, dass du tatsächlich nicht nur nach den Großbuchstaben B und D suchen möchstest, sondern nach längeren Texten. In dem anderen Fall würde eine Zeichenklasse genügen. Also statt "(?:B|D)" nur "[BD]".

          Falls die zu suchenden Zeichenketten aus einer anderen Variable stammen, musst du sie vorher mit preg_quote() "escapen".

          Und schließlich lässt sich auch das Muster für die Tags "<td>" und "</td>" toleranter gestalten.
          Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

          Kommentar


          • #6
            Zitat von fireweasel Beitrag anzeigen
            PHP-Code:
            preg_match_all('/<td>(?:B|D)</td>/'$src$treffer); 
            Das würde nicht funktionieren, weil / der Begrenzer ist. Wenn dann beispielsweise
            PHP-Code:
            '!<td>(?:B|D)</td>!' 
            Das explizite Unterdrücken des Subpattern Capturing mit ?: ist imho kontraproduktiv. Da muss er ja dann für jeden Treffer noch die Tags entfernen, statt gleich auf den Inhalt zugreifen zukönnen.
            Zuletzt geändert von AmicaNoctis; 07.09.2009, 22:10.
            [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
            Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
            Super, danke!
            [/COLOR]

            Kommentar


            • #7
              Richtig. Ich schiebe alle unabsichtlich eingebauten Fehler mal auf die Uhrzeit ...

              Also nochmal:

              PHP-Code:
              preg_match_all('/<td>(B|D)<\/td>/'$src$treffer); 
              Die gesuchten Teilstrings stehen dann im Array $treffer[1]

              ... oder auch so:

              PHP-Code:
              preg_match_all('/(?<=<td>)(?:B|D)(?=<\/td>)/'$src$treffer); 
              Da findest du das Gesuchte in $treffer[0].
              Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

              Kommentar


              • #8
                OffTopic:
                @fireweasel: Mir ist außer dir niemand bekannt, der Assertions nur um ihrer selbst Willen benutzt, zumal der Ausdruck dadurch nicht übersichtlicher wird. Baust du in deiner Freizeit zufällig Rube-Goldberg-Maschinen?
                [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                Super, danke!
                [/COLOR]

                Kommentar


                • #9
                  Zitat von AmicaNoctis Beitrag anzeigen
                  @fireweasel: Mir ist außer dir niemand bekannt, der Assertions nur um ihrer selbst Willen benutzt, ...
                  Nicht um ihrer selbst willen, sondern um das Ergebnis-Array zu vereinfachen.

                  ... zumal der Ausdruck dadurch nicht übersichtlicher wird.
                  Das war auch nicht beabsichtigt. Für die einfach gestrickten Gemüter (und für komplexere <td>-Tags) gibts ja die erste Variante.

                  Und wenn ich mehr Langeweile gehabt hätte, hätte ich auch noch eine Lösung mit preg_split() geliefert.

                  Baust du in deiner Freizeit zufällig Rube-Goldberg-Maschinen?
                  Ja, aber nicht zufällig sondern absichtlich und nur in PHP -- welches ja selbst eine Art Rube-Goldberg-Maschine zu sein scheint. Sonst bevorzuge ich einfache Apparate, die schnell, direkt und ohne Umstände eine Arbeit erledigen.

                  Eine Rube-Goldberg-Maschine ist ein komplexer Apparat, der eine sehr einfache Aufgabe unnötig langsam, indirekt und umständlich erledigt.
                  (Quelle: Wikipedia)

                  Also, der Ausdruck '/(?<=<td>)(?:B|D)(?=<\/td>)/' legt im Gegensatz zu '/<td>(B|D)<\/td>/' im Ergebnis-Array keine unnötigen Variablen für nicht gebrauchte Subpatterns an. Das spart Speicher. Im Falle von 'B' oder 'D' könnte man das natürlich verschmerzen. Was aber, wenn dort längere Texte stehen? Bei den heute immer noch üblichen HTML-Tabellen-Designs dürfte das ja keine Seltenheit sein.

                  Und Assertions sind schnell, nicht langsam. Also meistens ...

                  So, bevor jetzt die Anti-Microoptimierer jetzt noch ihren Senf dazugeben: Eigentlich mache ich das nur, um Nachfragen der Fragesteller zu provozieren. Je komplexer ein Ausdruck, um so eher wird nachgefragt (wenn Interesse an regulären Ausdrücken besteht) und nachgedacht, wie das im Einzelnen funktioniert. So beschäftigen sich die Threaderöffner oder die interessierten Mitleser intensiver mit der Sache, und der Lerneffekt ist größer.

                  ==
                  P.S.: Diesem Board fehlen eindeutig Ironie-Tags ...

                  P.P.S.: Ich fand den Film "Der Lauf der Dinge" cool und fahre ein (unkompliziertes) Auto der Marke "Honda", schwöre aber beim Leben meiner toten Katze, dass ich bis eben keinen blassen Schimmer hatte, was sich hinter dem Begriff Rube-Goldberg-Maschine verbirgt.
                  Zuletzt geändert von fireweasel; 08.09.2009, 12:10. Grund: diese quote-Tags machen mich noch mal wahnsinnig
                  Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

                  Kommentar


                  • #10
                    Zitat von fireweasel Beitrag anzeigen
                    Eigentlich mache ich das nur, um Nachfragen der Fragesteller zu provozieren. Je komplexer ein Ausdruck, um so eher wird nachgefragt (wenn Interesse an regulären Ausdrücken besteht) und nachgedacht, wie das im Einzelnen funktioniert. So beschäftigen sich die Threaderöffner oder die interessierten Mitleser intensiver mit der Sache, und der Lerneffekt ist größer
                    OffTopic:
                    Ok, gar nicht so schlecht die Idee. (Keine Ironie) Trotzdem würde ich in so einem Fall fast immer mit DOM arbeiten, auch wenn es langsamer ist. Die Lesbarkeit und Wartbarkeit ist viel größer, weil es in jeder Sprache gleich funktioniert, während bei RegEx die implementatorischen Unterschiede doch recht enorm sein können.
                    [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                    Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                    Super, danke!
                    [/COLOR]

                    Kommentar

                    Lädt...
                    X