Datendatei ohne Separatoren durchsuchen

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

  • Datendatei ohne Separatoren durchsuchen

    Hallo Forum,

    folgende Daten-Datei soll durchsucht werden:

    12345678901 111.11 2.22A 113.33 4
    23456789012 10.00 2.00F 3.00 5
    12455917373 1147.56 22.01S 53.00 6
    ...

    Die einzelnen Spalten sind also zwar durch Leerzeichen formatiert, aber nicht durch Separatoren wie ";" getrennt.

    Nun möchte ich nach der ersten Zahl suchen. Wird sie gefunden, sollen alle anderen Parameter in der Zeile zur weiteren Verarbeitung in Variablen geschrieben werden.

    Suche ich also nach "12345678901" sollen folgende Variablen belegt werden: $var1=111.11; $var2=2.22A; $var3=113.33; $var4=4.

    Die Datei ist ca. 15 MB groß. Wie gehe ich am besten vor, so dass die Suche nicht all' zu lange dauert?

    Vielen Dank für jeden Hinweis!

    Chriss

    PS: Dieses Forum habe ich nach einer ähnlichen Fragestellung durchsucht, habe aber nie etwas ohne Separatoren gefunden.

  • #2
    wenn du gar keinen Separator hättest, wärst du natürlich aufgeschmissen (bzw. könntest versuchen dir mit komplizierten RegExs zu helfen), aber in deinem Fall, kannst du ja einfach das Leerzeichen als Separator verwenden. Einfach ein

    PHP-Code:
    $arr explode(" ",$zeile); 
    und schon hast du alle parameter der Zeile in einem Array drin. Danach das erste Array-Element nach dem gewünschten Wert abfragen und mit den restlichen Arrayelementen das machen was du vorhast ...
    [color=red]Geht nicht[/color] ist keine Fehlermeldung

    Kommentar


    • #3
      Original geschrieben von Big Chief
      wenn du gar keinen Separator hättest, wärst du natürlich aufgeschmissen (bzw. könntest versuchen dir mit komplizierten RegExs zu helfen), aber in deinem Fall, kannst du ja einfach das Leerzeichen als Separator verwenden. Einfach ein

      PHP-Code:
      $arr explode(" ",$zeile); 
      und schon hast du alle parameter der Zeile in einem Array drin. Danach das erste Array-Element nach dem gewünschten Wert abfragen und mit den restlichen Arrayelementen das machen was du vorhast ...
      Oh! Da ist mein Posting nicht richtig formatiert worden. Es ist so, dass zwischen den Werten mehrere Leerzeichen stehen. D. h. das ganze ist quasi formatiert abgespeichert. Dezimalpunkt unter dezimalpunkt.

      Zur Verdeutlichung habe ich folgend die Leerzeichen durch "-" ersetzt:

      [FONT=courier new]
      12345678901----111.11----2.22A----113.33----4
      23456789012-----10.00----2.00F------3.00----5
      12455917373---1147.56---22.01S-----53.00----6
      ...[/FONT]

      Kann ich dann immer noch wie von Dir beschrieben vorgehen?

      Gruß,
      Chriss

      Kommentar


      • #4
        Ich würde es z.B. so lösen:
        PHP-Code:
        <?
        $datei = "
        12345678901----111.11----2.22A----113.33----4
        23456789012-----10.00----2.00F------3.00----5
        12455917373---1147.56---22.01S-----53.00----6
        ";

        $array = explode("\n",$zeile);

        for ($x = 0; $x <= count($array); $x++)
        {
            $variable = explode(" ",$array[$x]);
            if ($variable[0] == "DEINE_ABGEFRAGE_ID")
            {
                //weiterverarbeitung deiner Sachen .. mit Regulären ausdrücken oder sonstwas
            }
            
        }
        Wobei du dir den quark eigentlich sparen kannst, wenn du zeile für zeile die Datei einliest! - aber ich weiss ja jetzt nicht genau, wie du die Datei einliest!

        Am allereinfachsten wäre es sicherlich einen regulären ausdruck für die Suche zu benutzen - also sowas wie :

        preg_match("#(".$DEINEZAHL.")([a-zA-Z0-9]{ANZAHL_DER_MÖGLICHEN_ZEICHEN})#si,$datei,$match);

        und dann hast du im $match[2] die anderen variablen drinne, die du dann wiederum über explode etc weiterbenutzen kannst ...
        Du kannst natürlich in dem regulären Ausdruck auch gleich die anderen Teile alle rausfiltern - sofern du willst - ist ja alles kein thema :-) da sind dir quasi keine grenzen gesetzt!
        Aber k.a. ob die regulären ausdrücke langsamer sind als die andere Methode!
        C-Ya Toby

        Kommentar


        • #5
          Vielen Dank,

          das müsste so wohl funktionieren. Das werde ich mal probieren!

          Gruß,
          Chriss

          Kommentar


          • #6
            Also ich gehe mal davon aus, dass du die Datei zeilenweise ausliest .. und dann würde ich einfach noch den Befehl vor meinen zuvor angesprochenen schreiben.

            PHP-Code:
            $str preg_replace('#  +#',' ',$str); 
            Der sorgt dafür, dass aus vielen Leerzeichen immer nur ein einziges wird.

            "hallo welt" -> "hallo welt"

            Danach kannst du weitermachen wie ich zuvor beschrieben.
            (man hätte das alles wohl auch in einem Schritt machen können, aber ich finds so eigentlich sehr schön einfach)
            [color=red]Geht nicht[/color] ist keine Fehlermeldung

            Kommentar


            • #7
              Original geschrieben von Big Chief
              Also ich gehe mal davon aus, dass du die Datei zeilenweise ausliest .. und dann würde ich einfach noch den Befehl vor meinen zuvor angesprochenen schreiben.

              PHP-Code:
              $str preg_replace('#  +#',' ',$str); 
              Der sorgt dafür, dass aus vielen Leerzeichen immer nur ein einziges wird.

              "hallo welt" -> "hallo welt"

              Danach kannst du weitermachen wie ich zuvor beschrieben.
              (man hätte das alles wohl auch in einem Schritt machen können, aber ich finds so eigentlich sehr schön einfach)
              Ja, manche Dinge sind doch sehr viel einfacher als man zunächst denkt. Danke für den Hinweis!

              Gruß,
              Chriss

              Kommentar


              • #8
                Original geschrieben von Big Chief
                PHP-Code:
                $str preg_replace('#  +#',' ',$str); 
                Also ... es sollte wohl wirklich nicht schwierig sein für eine in dieser Form formatierte Datei einen Regulären Ausdruck zu entwickeln, der im Gegensatz zu diesem Big Chief quatsch ein sinnvolles Ergebnis liefert ... !

                Sowas hier:
                Code:
                preg_match("/^(\d{11})([ 0-9]{7}\.\d{2})([ 0-9]{5}\.\d{2})([A-Z])([ 0-9]{7}\.\d{2})([ 0-9]{5})$/i", $row, $matches);
                liefert dir z.B. in $matches[1] - $matches[6] die jeweiligen Spaltenwerte ... !
                Zuletzt geändert von goth; 16.04.2004, 00:43.
                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


                • #9
                  Vielen Dank nochmal für Eure Hinweise!
                  Das zeilenweise Auslesen der Datei mit Zuweisung der Spaltenwerte in ein
                  Array funktioniert problemlos. Ich finde also die gewünschte Zeile und kann
                  die entsprechenden Spaltenwerte wie gewünscht ausgeben.

                  Nur dauert das ganze recht lange. Die Datei ist 15 MB oder 190.000 Zeilen
                  groß. Befindet sich die zu suchende Zeile am Ende der Datei, so benötigt
                  mein Skript ca. 5 Sek bis es zur Ausgabe kommt. Gibt es eine Möglichkeit,
                  dass ganze zu beschleunigen? Dauert das zeilenweise Einlesen vielleicht
                  so lange?

                  Hier mein Skript zum Einlesen und finden der gewünschten Zeile in der Datei:
                  PHP-Code:
                  <?
                  $filename = "datei.txt";
                  $artikel="07129901520";   // exemplarisch soll hier nach gesucht werden
                  $preise = fopen("$filename", "r");
                  while($zeile=fgets($preise,1024)) 
                  {
                    $zeile = preg_replace('#  +#',' ',$zeile);
                    $zeilenwerte = explode(" ",$zeile);
                    if ($zeilenwerte[0] == $artikel)
                      {
                         echo "<p>Artikel gefunden!</p>";
                         // Spaltenwerte liegen vor
                         break;
                      }
                  }
                  fclose($preise);
                  ?>
                  @goth: Danke auch für Deinen regulären Ausdruck. Leider komme ich damit noch nicht so ganz zu Recht, so dass ich die konventionelle Methode gewählt habe. Dies dürfte aber das Zeitproblem nicht ausmachen, oder?


                  Gruß,
                  Chriss

                  Kommentar


                  • #10
                    mit file() liest du alles auf einmal in den Speicher rein und mit foreach
                    kannst du die Zeilen durchklopfen, ist IMHO schneller, da Zugriffzeit
                    von RAM um das vielfach schneller als von HD. Schau mal hier

                    Kommentar


                    • #11
                      vielleicht solltest du mal überlegen, eine solche datenmengen in eine
                      datenbank zu verfrachten ... wenn das nicht geht, sollte das hier schneller
                      laufen:
                      PHP-Code:
                      <?php
                      $d 
                      file("datei.txt");
                      $artikel="12345678901"
                      foreach(
                      $d as $v)
                      {
                        if (
                      strstr($v,$artikel))
                        {
                              echo 
                      "<p>Artikel gefunden!</p>";
                              
                      // hier zerlegst du den GEFUNDENEN datensatz
                              
                      break;
                        }
                      }
                      ?>
                      Kissolino.com

                      Kommentar


                      • #12
                        OffTopic:
                        @wurzel, ätschibätschi, bin schneller

                        Kommentar


                        • #13
                          Original geschrieben von asp2php
                          OffTopic:
                          @wurzel, ätschibätschi, bin schneller
                          file() ist nicht (unbedingt) entscheidend ... es gilt, die regex aus der schleife zu zerren ... ausserdem hat der igel auch gegen den hasen gewonnen :P
                          Kissolino.com

                          Kommentar


                          • #14
                            Original geschrieben von Wurzel
                            vielleicht solltest du mal überlegen, eine solche datenmengen in eine
                            datenbank zu verfrachten ... wenn das nicht geht, sollte das hier schneller
                            laufen:
                            PHP-Code:
                            <?php
                            $d 
                            file("datei.txt");
                            $artikel="12345678901"
                            foreach(
                            $d as $v)
                            {
                              if (
                            strstr($v,$artikel))
                              {
                                    echo 
                            "<p>Artikel gefunden!</p>";
                                    
                            // hier zerlegst du den GEFUNDENEN datensatz
                                    
                            break;
                              }
                            }
                            ?>
                            Danke für den Hinweis. Leider funktioniert das Skript aber so nicht. Es kommt die Fehlermeldung:

                            Fatal error: Allowed memory size of 41943040 bytes exhausted (tried to allocate 35 bytes) in /pages/..../abfrage.php on line 2

                            Woran könnte es liegen?

                            Chriss

                            Kommentar


                            • #15
                              Original geschrieben von Chriss
                              woran könnte es liegen?
                              bissi wenig speicher für die datei in kombination mit file() .... dann ersetz' file() durch die fopen/fgets konstruktion mit while ...
                              Kissolino.com

                              Kommentar

                              Lädt...
                              X