String druchsuchen und ggf. teile davon entfernen

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

  • String druchsuchen und ggf. teile davon entfernen

    Hallo zusammen,


    Mal wieder - sonst hätte ich kaum eine Frage - stehe ich tierisch aufm Schlauch.

    Folgendes Vorhaben kurz geschildert

    Ich habe String der im grossen und ganzen meist ähnlich ausschaut. Bsp:

    NAME1: TEXT-TEXT-TEXT *644938548 (14.12.2008 19:21:22)
    NAME2: TEXT-TEXT-TEXT *438.832.192 MEHR TEXT (02.12.2008 19:37:37)
    NAME3: TEXT-TEXT-TEXT 509.687.198 MEHR TEXT (29.09.2008 16:08:54)
    NAME4: TEXT-TEXT (15.08.2008 16:46:23)


    Das Endziel wäre es nun, dass ich jede Zeile einzeln verwenden/weiterverarbeiten kann. Jedoch gibt es dabei einiges zu beachten:

    1. NAME muss entfernt werden (bereits gelöst)
    PHP-Code:
    $text $_POST['inhalt'];
    $zeile explode("\r\n"$text);
    foreach (
    $zeile AS $ntrennen) {
        
    $ohnename explode(":"$ntrennen2);
        echo 
    "$ohnename[1] <br /><br />";

    2. Die immer 9-stellige Nummer welche nicht immer gleich geschrieben wird und nicht immer am selben Ort in der Zeile steht (aber auch nicht immer vorhanden ist) muss zum einen aus der Zeile entfernt und zum anderen als Variable zwecks weiterverarbeitung ver-/gemerkt werden
    Mögliche Versionen der 9-stelligen Nummer:
    Mit Stern: *123456789
    Mit Stern und Punkten: *123.456.789
    Ohne Stern mit Punkten: 123.456.789
    Ohne Stern ohne Punkte: 123456789

    3. Das Datum, welches immer am Ende der Zeile steht ebenfalls (Format ist ebenfalls immer das selbe) entfernen, zu einem UNIX-Timestamp umwandeln und in einer Variable zwischenspeichern.


    Ich komme hier einfach auf keinen grünen Zweig, finden keinen wirklich schlauen und/oder für mich möglichen (von den Fähigkeiten her..) Ansatz um Punkt 2 und 3 umzusetzen. Daher die Frage an euch, wie ihr an sowas heran gehen würdet.

    Gruss & Danke im Voraus für Ratschläge, Ideen, etc. :-)

  • #2
    um die Zahl und das Datum zu entfernen benutzt Du am besten einen regulären ausdruck.
    *123.456.789 entspricht dann etwa sowas \*?[0-9\.]{9,11}
    Wobei Du hier auch das Datum treffen kannst, also würde ich das Datum zuerst behandeln oder Du verfeinerst den Ausdruck
    Das Datum ist auch einfach, es steht immer in den klammern und hat immmer das gleiche Format oder es steht immer am schluss und ist immer gleich lang, dann kannst Du auch nur mit substr($str,-20,19) und ähnlichen Funktionen arbeiten
    Zuletzt geändert von MelloPie; 16.12.2008, 06:54.
    Beantworte nie Threads mit mehr als 15 followups...
    Real programmers confuse Halloween and Christmas because OCT 31 = DEC 25

    Kommentar


    • #3
      Hallo,


      Punkt 3 (Datum raussuchen) habe ich nun gelöst - die verarbeitung zum Timestamt ist dann nur noch Kleinkram..

      PHP-Code:
      $ohnename explode(":"$ntrennen2);
      $laenge strlen($ohnename[1]);
      $start $laenge 21;
      $datum substr($ohnename[1], $start21); 
      Punkt 2 (Nummer suchen) bereitet mit aber weiterhin Probleme. Der vorgegebene preg_match (danke übrigens dafür) funktioniert nur dann korrekt, wenn im Text davor keine Zahlenreihe/handgeschriebenes Datum auftaucht. Zugegeben, daran habe ich auch nicht gedacht bzw. es nicht beachtet. Wenn im Text nun also zb. ein 19.12.2008 vorkommt schnappt sich das der regex und gibt es mir als Nummer zurück. Ich muss zugeben, RegEx ist für mich ein Buch mit zu vielen Seiten und das Thema ist bekanntlich nicht ohne. Kann man diesen noch mehr 'einschränken' und/oder einen genaueren 'Filter' geben den er zu beachten hat?


      Gruss

      Kommentar


      • #4
        Die Not macht erfinderisch

        Da ich mit RegEx wie bereits gesagt auf Kriegfuss stehe habe ich mir versucht anders zu helfen - in der Tat sogar erfolgreich, auch wenns nicht optimal ist.

        Das ganze mal gepostet:
        PHP-Code:
        $text "NAME1: TEXT-23.11.2008-TEXT *644938548 (14.12.2008 19:21:22) \n 
        NAME2: TEXT-TEXT-TEXT *438.832.192 MEHR TEXT (02.12.2008 19:37:37) \n 
        NAME3: TEXT-TEXT-TEXT 509.687.198 MEHR TEXT (29.09.2008 16:08:54) \n
         NAME4: TEXT-TEXT (15.08.2008 16:46:23)"
        $zeile explode("\r\n"$text); // Zeilenumbrüche entfernen
        foreach ($zeile AS $ntrennen) {
            
        $ohnenick explode(":"$ntrennen2); // NAME entfernen
            
        $pattern '#\*?[0-9\.]{9,11}#is';  // Nach Nummer suchen
            
        $result preg_match_all($pattern$ohnenick[1], $subpattern);
            
        $anzahl count($subpatternTRUE);
            foreach (
        $subpattern[0] AS $inhalt) {
                
        $unerlaubt = array("*"=>"""."=>""":"=>"""("=>""")"=>""" "=>""); 
                
        $nr strtr($inhalt$unerlaubt);  // Unterlaubte Zeichen aus Nummer entfernen
                
        $laengezahl strlen($nr);
                if (
        $laengezahl '9' || $nr == $nummer) { // Prüfen ob Nummer auch 9 Zeichen enthält, sonst verwerfen
                    
        unset($nr); 
                }
                else {
                    
        $nummer $nr;
                }
            }
            
        $laenge strlen($ohnenick[1]);  // Stringlänge ermitteln
            
        $start $laenge 21;  // Startposition für substr ermitteln
            
        $datum substr($ohnenick[1], $start21);
            echo 
        "$ohnenick[1] <br /><b>NR:</b> $nummer <br /><b>Datum:</b> $datum<br /><br />";
            unset(
        $nummer);

        Mit Sicherheit überarbeitungswürdig - wenn man von RegEx mehr verstehen würde. *g*

        Kommentar


        • #5
          hier mal mit RegEx:

          PHP-Code:
          $str 'NAME1: TEXT-TEXT-TEXT *644938548 (14.12.2008 19:21:22)
          NAME2: TEXT-TEXT-TEXT *438.832.192 MEHR TEXT (02.12.2008 19:37:37)
          NAME3: TEXT-TEXT-TEXT 509.687.198 MEHR TEXT (29.09.2008 16:08:54)
          NAME4: TEXT-TEXT (15.08.2008 16:46:23)'
          ;

          // parse lines               1:text     2:day   3:month  4:year  5:hour  6:min    7:sec
          if (preg_match_all('@^.+?:\s*(.*?)\s*\((\d{2})\.(\d{2})\.(\d{4}) (\d{2}):(\d{2}):(\d{2})\)\s*$@m'$str$hits)) {
              for (
          $i 0$i count($hits[0]); $i ++) {
                  
          // parse number   1:text1     2:number                3:text2
                  
          if (preg_match('@^(.*?)\s*\*?(\d{3}\.?\d{3}\.?\d{3})\s*(.*?)$@'$hits[1][$i], $sub)) {
                      
          $text trim($sub[1].' '.$sub[3]);
                      
          $number intval(str_replace('.'''$sub[2]));
                  }
                  else {
                      
          $text $hits[1][$i];
                      
          $number 0;
                  }
                  
          $timestamp mktime($hits[5][$i],$hits[6][$i],$hits[7][$i],$hits[3][$i],$hits[2][$i],$hits[4][$i]);

                  echo 
          '$text: '.$text.'<br />';
                  echo 
          '$number: '.$number.'<br />';
                  echo 
          '$timestamp: '.$timestamp.'('.date('Y-m-d H:i:s'$timestamp).')<br /><br />';
              }

          edit: blöderweise nimmt das forum alle backslashes raus. du musst dir in den ausdrücken vor jedem "d" und "s" einen vorstellen und an der stelle wo zwei "*" aufeinander folgen vor dem zweiten. Außerdem gehören bei (\d{3}\.?\d{3}\.?\d{3}) vor den punkten, muss aber in dem fall nicht sein.

          edit2: anscheinend nur in dem php-block. also hier die ausdrücke:
          '@^.+?:\s*(.*?)\s*\((\d{2})\.(\d{2})\.(\d{4}) (\d{2})\d{2})\d{2})\)\s*$@m'
          '@^(.*?)\s*\*?(\d{3}\.?\d{3}\.?\d{3})\s*(.*?)$@'
          Zuletzt geändert von MarkusW; 19.12.2008, 10:45.

          Kommentar

          Lädt...
          X