Ankündigung

Einklappen
Keine Ankündigung bisher.

Probleme bei Verwendung der reguären Ausdrücke

Einklappen

Neue Werbung 2019

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

  • Probleme bei Verwendung der reguären Ausdrücke

    Ich habe mal wieder ein Problem:

    Ich würde gern aus einem Browser-Game die Rangliste auslesen.
    Das versuche ich gerade so zu bewerlstelligen:

    PHP-Code:
    <?php
    if(preg_match('#\<tr\>\<td class\=\"rank\"\>(.*)\</td\>\<td class\=\"name\"\>(.*)\</td\>\<td class\=\"sort_val\"\>(.*)\</td\>\</tr\>#U'file_get_contents('http://hackthenet.org/_htn.php/ranking/cluster?server=1'), $hits)) {
      echo 
    preg_replace('#\<tr\>\<td class\=\"rank\"\>(.*)\</td\>\<td class\=\"name\"\>(.*)\</td\>\<td class\=\"sort_val\"\>(.*)\</td\>\</tr\>#U''\\1, \\2, \\3'$hits[0], 1);
    } else {
      echo 
    'fehler';
    }
    ?>
    Die URL zum Game steht ja im Code dabei (Link zur Rangliste).

    Irgendwie funktioniert das aber nur so weit, das das nur erste Ergebnis ausgelesen wird. Wenn ich jetz das Limit von 1 wieder aus der Funktion preg_match() entferne, dann wird die gesamte Rangliste inklusive Tabellen erzeugt.

    Ich hätte es gerne, das die gesamte Rangliste ausgelesen und mit Zeilenumbrüchen untereinander geschrieben werden. Ungefähr in dem Stil:

    Code:
    Rang1, Name1, Punkte1
    Rang2, Name2, Punkte2
    Hoffe ihr könnt mir helfen.

    mfg SilentSight

  • #2
    Also zuerst einmal kannst du das Escapen von < und > weglassen, da diese Zeichen in regulären Ausdrücken keine besondere Bedeutung haben.

    Und dann zu deinem eigentlichen Problem: Du überprüfst mit einer if-Abfrage, ob du einen einzigen Match findest. Dieser wird in $hits gespeichert. In $hits
    steht aber nur der allererste Match aus der Tabelle, alle anderen Matches der Rangliste sind da nicht drin.
    Du musst entweder preg_match_all() verwenden und nachher über das Array iterieren oder du musst manuell durch alle Matches mit einzelnen preg_match() iterieren, was ich jedoch eher unpraktisch finde.

    Ich verstehe aber nicht ganz, warum du in der preg_replace() Funktion das Limit 1 benutzt. Damit wird ja jeder eingeklammerte Teil nur 1x ersetzt => du solltest die erste Zeile im von dir vorgegebenen Format zurückkriegen, den Rest aber wie auf der Website.

    Kommentar


    • #3
      Danke für deine Antwort.
      Hab jetz das Script an preg_match_all angepasst, aber
      1. glaube ich, dass ich es leichter geht.
      2. kommt darunter noch mal der ganze Salat durcheinandergewürfelt

      Es sieht jetz so aus:
      PHP-Code:
      <?php
      if(preg_match_all('#<tr><td class="rank">(.*)</td>\<td class="name">(.*)</td>\<td class="sort_val">(.*)</td></tr>#Uis'file_get_contents('http://hackthenet.org/_htn.php/ranking/cluster?server=1'), $hits)) {
        foreach(
      $hits as $key => $value) {
          foreach(
      $value as $key2 => $value2) {
            echo 
      preg_replace('#<tr><td class="rank">(.*)</td><td class="name">(.*)</td><td class="sort_val">(.*)</td></tr>#Uis'"\\1, \\2, \\3<br />"$hits[$key][$key2]);
          }
        }
      }
      ?>
      Die Ausgabe:
      Code:
      1, 101 HackNET, 1.504.376
      2, THC THC-Crew, 833.370
      3, FFC First Family Cluster, 506.678
      4, THC-L1 THC-Crew, 384.428
      5, -=]SX[=- -SinteX-, 376.686
      6, 666 Betreutes Wohnen, 368.633
      7, -[MF]- Maverick Force, 271.337
      8, HackerZ[L2] HackerZ[L2], 254.452
      9, >>]TI[<< The Illuminati², 248.350
      10, >GO< GotOwned, 227.321
      12345678910101 HackNETTHC THC-CrewFFC First Family ClusterTHC-L1 THC-Crew-=]SX[=- -SinteX-666 Betreutes Wohnen-[MF]- Maverick ForceHackerZ[L2] HackerZ[L2]>>]TI[<< The Illuminati²>GO< GotOwned1.504.376833.370506.678384.428376.686368.633271.337254.452248.350227.321
      Mit Salat mein ich halt den Teil nach Nummer 10.
      Kannst du mir evtl sagen wo das herkommt, bzw. wie ich das umgehen kann?

      Kommentar


      • #4
        Habe den Code mal bissl verbessert

        PHP-Code:
        <?php
        if(preg_match_all('#<tr><td class="rank">(.*)</td>\<td class="name">(.*)</td>\<td class="sort_val">(.*)</td></tr>#Uis'file_get_contents('http://hackthenet.org/_htn.php/ranking/cluster?server=1'), $hitsPREG_SET_ORDER)) {
          foreach(
        $hits as $value) {
            echo 
        $value[1].', '.$value[2].', '.$value[3].'<br />'
          
        }
        }
        ?>
        Das Problem mit dem komischen Zeugs am Schluss kommt daher, dass man sich mal genau anschauen muss, wie preg_match() bzw preg_match_all() das Match-Array aufbaut. Ist auch ziemlich gut im PHP-Manual erklärt. Dort findet man dann auch noch die Sort-Flags, die in diesem Fall sehr hilfreich sind. Deshalb habe ich das PREG_SET_ORDER Flag gesetzt, das bewirkt, dass alle Matches (die Klammerausdrücke) einer Zeile im selben Array stehen und nicht alli Matches des ersten Klammerausdrucks in einem Array und alle Matches des zweiten Klammerausdrucks in einem anderen Array etc....

        Falls du was noch nicht verstanden hast, einfach fragen.

        Kommentar


        • #5
          Ah, schon viel besser, danke.
          Muss mich echt mal mehr mit den regulären Ausdrücken beschäftigen...
          Hab nur im Moment nich so viel Zeit...

          Neues Problem:

          Wenn ich jetz nach einem Cluster suche, dann wird es fett dargestellt.
          Wie kann ich meinen Regex jetz so umwandeln, dass er auf beides, auf fett und nicht fett matcht?

          Ich habe es folgendermaßen versucht:

          PHP-Code:
           <?php
          if(preg_match_all('#<tr(\sclass="active"|^\sclass="active")><td class="rank">(.*)</td>\<td class="name">(.*)</td>\<td class="sort_val">(.*)</td></tr>#Uis'file_get_contents('http://hackthenet.org/_htn.php/ranking/cluster?server=1'), $hitsPREG_SET_ORDER)) {
            foreach(
          $hits as $value) {
              echo 
          $value[1].', '.$value[2].', '.$value[3].'<br />';
            }
          }
          ?>
          Das gibt aber nur das gefundene Cluster aus, und auch nicht so wie es geplant war.

          Hoffe dafür gibts, wie für vieles andere auch ne Lösung

          Kommentar


          • #6
            Ich bin jetzt nicht sicher, ob ich dich richtig verstanden habe.

            Möchtest du die fett markierten Einträge einfach ganz normal auslesen und ausgeben oder möchtest du die auch speziell ausgeben?

            Ich habs jetzt nicht ausprobiert aber damit sollte es eigentlich egal sein, ob eine Zeile fett ist oder nicht:

            Code:
            #<tr[^>]*><td class="rank">(.*)</td>\<td class="name">(.*)</td>\<td class="sort_val">(.*)</td></tr>#Uis

            Kommentar


            • #7
              Hab leider erst wieder heute Abend Zeit es zu testen.
              Geht das nicht auch so, dass nur die Tabellenreihen mit der Klasse active gematcht werden?

              Das mit dem speziell darstellen, wäre meine nächste Frage gewesen (will ja nich zu viele Probleme auf einmal hier rein stellen ).

              Hab mir schon was überlegt nähmlich so:

              PHP-Code:
              if((preg_match_all('#<tr[^>]*><td class="rank">(.*)</td>\<td class="name">(.*)</td>\<td class="sort_val">(.*)</td></tr>#Uis'file_get_content(...), $out) || (preg_match_all('#<tr><td class="rank">(.*)</td>\<td class="name">(.*)</td>\<td class="sort_val">(.*)</td></tr>#Uis'file_get_content(...), $out)) 
              Ich habe nur die Vorahnung, dass es ziiiieeemlich umständlich und außerdem unübersichtlich ist...

              Kommentar


              • #8
                Achso sorry, hatte dich falsch verstanden.
                Wenn ich das jetzt richtig mitgekriegt habe, willst du noch ne RegExp, die nur die fett gedruckten Zeilen ausliest?

                Zu deinem geposteten Code-Stück: Das ist irgendwie doppelt geprüft ^^ die erste RegExp, die ich zuletzt gepostet hatte, matcht sowohl fette als auch normale Zeilen. Deshalb verstehe ich nicht ganz, warum du das zweimal überprüfen willst. Zudem würde so das Array $out immer nur die Treffer des zweiten preg_match_all() beinhalten, da das vorherige $out-Array überschrieben wird.

                Kommentar


                • #9
                  Oh man...
                  Ich glaube ich hab da nen Wurm reingebracht...
                  Hab des Code-Stück zuhause und hab des mit meinem alten Regex gemacht, noch nicht mit deinem... Sry

                  Nein, ich will nicht nur die fetten Zeilen matchen, sondern alle, nur dass ich die fetten Zeilen hervorheben will, also z. B. wieder fett machen.

                  Kommentar


                  • #10
                    Ach ja.
                    Ich meinte, ob es möglich wäre, dass alle Tabellenreihen ausgelesen werden, aber bwi <tr> nicht mit irgendwas dahinter sondern nur mit class="active".

                    Kommentar


                    • #11
                      Also zu dem Problem, dass die Zeilen, die auf der Page fett sind, auch bei dir fett dargestellt werden:
                      PHP-Code:
                      <?php
                      if(preg_match_all('#<tr([^>]*)><td class="rank">(.*)</td>\<td class="name">(.*)</td>\<td class="sort_val">(.*)</td></tr>#Uis'file_get_contents('http://hackthenet.org/_htn.php/ranking/cluster?server=1'), $hitsPREG_SET_ORDER)) {
                        foreach(
                      $hits as $value) {
                          if(!empty(
                      $value[1])) echo '<b>'.$value[2].', '.$value[3].', '.$value[4].'</b><br />';
                          else echo 
                      $value[2].', '.$value[3].', '.$value[4].'<br />';
                        }
                      }
                      ?>
                      Damit steht in den Array-Index 1 immer alles, was noch nach dem "tr" im gleichen Tag steht. Wenn da nix drinsteht, wird es auf der Page auch nicht fett angezeigt => alles wird normal ausgegeben. Steht da hingegen was drin (man könnte auch eine explizite Überprüfung des Strings machen), wird es auch bei dir fett ausgegeben.

                      Zur Sache, dass da nur " class="active" stehen soll und nix anderes: Gibt es denn Fälle, wo da noch was anderes steht?
                      Und ansonsten kannst du die Überprüfung
                      PHP-Code:
                      if(!empty($value[1])) ... 
                      einfach durch
                      PHP-Code:
                      if($value[1]==' class="active"') ... 
                      ersetzen, dann solltest du den gewünschten Effekt auch haben.

                      Kommentar


                      • #12
                        Habs inzwischen gelöst, aber deine Vorschäge find ich super. DANKE für deine Mühe

                        Kommentar

                        Lädt...
                        X