Regulärer Ausdruck... funktoniert nicht immer wie gewollt.

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

  • Regulärer Ausdruck... funktoniert nicht immer wie gewollt.

    Hallo,

    Ich habe hier ein Copy&Paste eines Webseiteninhalts, aus dem ich verschiedene Daten extrahieren will. So ein C&P sieht beispielsweise so aus:


    Galaxie 4 - System 3 - Position Systemzentrum: -10011.-11923.9295
    1 Tattooine Darth_Vader [DZ] 552 XXX
    2 Kappeln-2 Ghost-Raider [MOWL] 118 XXX
    3 ODINSFESTE THYRRUS [Pimps] 5.482 XXX
    4 unknown Hagbard§ Celine [DZ] 377 XXX
    5 Bahamut 7 Red Claw4 [UnAt] 280 XXX
    6 War The master [TB] 401 XXX
    7 unknown alex-one 358 XXX
    8 Trantor Tom Paris [UFoPs] 83 XXX
    9 XXX
    10 unknown spubbl [=SW=] 121 XXX
    11 unknown alex-one 159 XXX


    [mehr ..]
    Problemstellung: Hier soll mittels RegExp und preg_match_all pro Zeile Planetennummer, Planetenname, Spielername, Allianzname (immer in eckicken Klammern), Punktzahl extrahiert werden. Alle Namen können hierbei alle Zeichen, inklusive Leerzeichen, enthalten, die Punktzahl kann einen Tausender-Trenner (.) enthalten. Die einzelnen Elemente sind durch mindestens 2 Leerzeichen getrennt.

    Somit kam ich zu folgendem regulären Ausdruck:

    PHP-Code:
                $suchmusterPlaneten    =    "%([0-9]+)\s{2,}([\S\s]+)\s{2,}([\S\s]+)\s{2,}(\[[\S\s]+\])\s{2,}([0-9\.]+)\s{2,}xxx%Uim"

    So, das Suchmuster klappt auch perfekt, solange eine Zeile ALLE Elemente enthält. Sobald aber wie z.B. bei der mit "9" beginnenden Zeile alles bis auf das XXX am Schluss fehlt - oder irgendeine andere Angabe, dan führt die Abfrage zu fehlerhaften Ergebnissen. Bei Zeile 9 z.B.:

    Array
    (
    [0] => Array
    (
    [0] => 1 Tattooine Darth_Vader [DZ] 531 XXX

    [1] => 2 Kappeln-2 Ghost-Raider [MOWL] 118 XXX

    [2] => 3 ODINSFESTE THYRRUS [Pimps] 548 XXX

    [3] => 4 unknown Hagbard Celine [DZ] 377 XXX

    [4] => 5 Bahamut 7 Red Claw [UnAt] 280 XXX

    [5] => 6 War The master [TB] 401 XXX

    [6] => 7 unknown alex-one 358 XXX

    [7] => 8 Trantor Tom Paris [UFoPs] 83 XXX

    [8] => 9 klar nivhz 999 XXX\r\n10 unknown spubbl [SW=] 121 XXX

    [9] => 11 unknown alex-one 159 XXX

    [10] => 12 jeporgia Karlson 204 XXX
    )

    also wird planet 10 nicht richtig gefunden. ich habe schon versucht, den String vor der Suche per

    PHP-Code:
    str_replace (array("\r","\n")," ",$String); 
    von den \r und \n zu befreien - aber das half nichts, das Ergebnis war identisch mit dem obigen (\r und \n sind immer noch drin).

    Kann man die RegExp irgendwie so schreiben, dass sie sowas abfängt und Zeilen, in denen Spielername und Planetenname fehlen NICHT berücksichtigt?


    Ich danke schon mal für eure Hilfe...

    mardeluk

  • #2
    Warum benutzt Du nicht
    PHP-Code:
    explode(); 

    Kommentar


    • #3
      U.a. deswegen, weil das oben gepostete nicht der gesamte Copy&Paste der Seite ist - der ist bis zu 4x so lang - ich hab nur den relevanten Teil hier hineinkopiert.

      Und wenn ich z.B. an allen Stellen, wo zwei aufeinanderfolgende Leerzeichen per explode trennen würde, dann hätte ich bei Zeilen, wo Elemente fehlen, zuiele Array-elemente. Ausserdem muss das Script in allen Browsern funktionieren - und das C&P der Seite sieht leider je nach Browser unterschiedlich aus. weswegen mir die Vorgehensweise mittels regExp die sinnvollste erscheint.
      Zuletzt geändert von mardeluk; 30.07.2006, 12:42.

      Kommentar


      • #4
        Und wenn ich z.B. an allen Stellen, wo zwei aufeinanderfolgende Leerzeichen per explode trennen würde, dann hätte ich bei Zeilen, wo Elemente fehlen, zuiele Array-elemente.
        Mittels
        PHP-Code:
        array_splice(); 
        könntest Du entsprechende Elemente (Leerzeichen) aus dem Array entfernen.
        U.a. deswegen, weil das oben gepostete nicht der gesamte Copy&Paste der Seite ist - der ist bis zu 4x so lang - ich hab nur den relevanten Teil hier hineinkopiert.
        Das kann ich nicht riechen. Deine Aussage war:
        Ich habe hier ein Copy&Paste eines Webseiteninhalts, aus dem ich verschiedene Daten extrahieren will. So ein C&P sieht beispielsweise so aus:

        Kommentar


        • #5
          So, das Suchmuster klappt auch perfekt, solange eine Zeile ALLE Elemente enthält.
          Works as designed, die Blöcke "([Ss]+)s{2,}" in deinem Ausdruck sind eben nicht optional.

          Kommentar


          • #6
            @gruenspan: sorry, da hab ich mich wirklich unglücklich ausgedrückt, da hast Du recht.

            @onemorenerd hm - wie kann man sie denn besser machen?

            Kommentar


            • #7
              PHP-Code:
              $sep 's{2,}';
              $num '([0-9]+)';
              $ord '([0-9\.]+)'// Forum frißt Backslash vor .
              $str '([Ss]+)';
              $end 'xxx';
              $p '%'.$num.$sep.'('.$str.$sep.'){0,3}'.$ord.$sep.$end.'%Uim'

              Kommentar


              • #8
                sieht auf jeden Fall strukturierter aus als mein BandwurmRegEx ;-) danke!

                Nur... Ergebnis ist genau das gleiche

                Array
                (
                [0] => Array
                (
                [0] => 1 Tattooine Darth_Vader [DZ] 531 xxx
                [1] => 2 Kappeln-2 Ghost-Raider [MOWL] 118 xxx
                [2] => 3 ODINSFESTE THYRRUS [Pimps] 548 xxx
                [3] => 4 unknown Hagbard Celine [DZ] 377 xxx
                [4] => 5 Bahamut 7 Red Claw [UnAt] 280 xxx
                [5] => 6 War The master [TB] 401 xxx
                [6] => 7 unknown alex-one 358 xxx
                [7] => 8 Trantor Tom Paris [UFoPs] 83 xxx
                [8] => 9 xxx\r\n10 unknown spubbl [=SW=] 121 xxx
                [9] => 11 unknown alex-one 159 xxx
                [10] => 12 jeporgia Karlson 204 xxx
                Kann ich irgendwie sagen, dass $str KEINE Dreierfolge von "x" enthalten darf? (Das x darf ich ja nicht generell ausschliessen, [^x] ist also keine Lösung). Desweiteren versteh ich nicht, wieso an der Fehlerstelle ein \r\n auftaucht - welches ich auch durch Vorbehandlung mittels str_replace nicht entfernen kann.

                Kommentar


                • #9
                  Varianten:
                  (1) ein grosses oder: (?:^XXX$|planetenzeile)
                  (2) ein explode auf 'XXX\n', wobei das \n gegen Spielernamen mit XXX schützt.
                  (3) ein preg_split auf 'XXX\n'. das würde, mit Erweiterungen, whitespace um das XXX besser abfangen.

                  Kommentar


                  • #10
                    hm... ich hab noch eine Variante - zunächst Zeilenweises aufteilen:

                    $suchmusterPlaneten = '%[0-9]{1,2}.*xxx%U';

                    und dann per explode weiterbearbeiten.

                    Aber nach wie vor hab ich ein Problem: Wenn ich den Quellstring per echo ausgebe, bekomme ich alle Steuerzeichen ( \r und \n) angezeigt. Will ich sie aber mit Leerzeichen ersetzen per
                    PHP-Code:
                    $newString str_replace(array("\r","\n")," ",$quellstring); 
                    ... und gebe dann $newString per echo() aus, dann sind alle \r und \n immer noch da... warum?

                    Kommentar


                    • #11
                      kommt drauf an, ob du 'backslash n' 'backslash r'ersetzen musst oder ein ascii LF und CR. Weil mit echo kannst du eigentlich ascii LF und CR gar nicht sehen. Nur deswegen denke ich:
                      $newString = str_replace(array('\r','\n')," ",$quellstring);

                      Kommentar


                      • #12
                        Ich danke euch allen - das Forum war mir echt eine tolle Hilfe! Habe es nun ein wenig anders gelöst, aber die Anregungen hier haben mir mit auf die Sprünge geholfen.

                        Ein dickes DANKE an dieser Stelle!

                        mardeluk

                        Kommentar

                        Lädt...
                        X