Jo: String verarbeiten

Hallo,

habe folgende Aufgabe: Ich extrahiere aus Header dem von Bildern umfangreiche Informationen und dabei kommt sowas als Textstring raus:

Driver: GTiff/GeoTIFF
Size is 6400, 9600
Pixel Size = (10.00000000,-10.00000000)
Metadata:
TIFFTAG_SOFTWARE=Adobe Photoshop CS Windows
TIFFTAG_RESOLUTIONUNIT=2 (pixels/inch)
Corner Coordinates:
Upper Left ( 44000.000, 142000.000)
Upper Right ( 108000.000, 142000.000)
Overviews: 3200x4800, 1600x2400, 800x1200, 400x600, 200x300
usw...

Nun möchte ich immer die Metainformationen zwischen zwei Ausdrücken extrahieren.
z.B. zwischen "Driver:" und "Size is" = "GTiff/GeoTIFF"
oder zwischen "Size is " und "Pixel Size" = "6400, 9600"
usw.

Wie gehe ich dabei am besten vor? Mit regulären Ausdrücken? Gibts für sowas irgendwo ein Beispiel?
Danke
Jo

  1. Hello,

    Wie gehe ich dabei am besten vor? Mit regulären Ausdrücken? Gibts für sowas irgendwo ein Beispiel?

    Das hat Christian neulich erst wunderbar erklärt.
    Das Stichwort heißt Assertions
    Für Deinen Fall müssten die auch ohne weiteres passen.

    Ist schon im Archiv, aber noch nicht lange...

    Harzliche Grüße vom Berg
    http://bergpost.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau
    Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

    1. Hello,

      seth war's...

      Ist schon im Archiv, aber noch nicht lange...

      http://forum.de.selfhtml.org/archiv/2007/11/t161925/#m1053473
      und
      http://forum.de.selfhtml.org/archiv/2007/11/t161850/#m1053364

      Harzliche Grüße vom Berg
      http://bergpost.annerschbarrich.de

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      Nur selber lernen macht schlau
      Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

  2. (Hallo|Hi(ho)|Tag) Jo,

    habe folgende Aufgabe: Ich extrahiere aus Header dem von Bildern umfangreiche Informationen und dabei kommt sowas als Textstring raus:

    Driver: GTiff/GeoTIFF
    Size is 6400, 9600
    Pixel Size = (10.00000000,-10.00000000)
    Metadata:
    TIFFTAG_SOFTWARE=Adobe Photoshop CS Windows
    TIFFTAG_RESOLUTIONUNIT=2 (pixels/inch)
    Corner Coordinates:
    Upper Left ( 44000.000, 142000.000)
    Upper Right ( 108000.000, 142000.000)
    Overviews: 3200x4800, 1600x2400, 800x1200, 400x600, 200x300
    usw...

    Nun möchte ich immer die Metainformationen zwischen zwei Ausdrücken extrahieren.
    z.B. zwischen "Driver:" und "Size is" = "GTiff/GeoTIFF"
    oder zwischen "Size is " und "Pixel Size" = "6400, 9600"
    usw.

    Hierzu würde ich preg_match() etwa so einsetzen:

      
    $offset = 0;  
    // schleife  
      // $rx muss natuerlich in jedem Durchgang anders aufgebaut sein  
      $rx = '/(Driver:)(.*?)(?Size is)/s';  
      if ( !preg_match($rx, $text, $treffer, PREG_OFFSET_CAPTURE, $offset) ) {  
        // Fehlerbehandlung  
        ...  
        break;  
      }  
      // gefunden  
      // in $treffer[1] steht der gesuchte "Zwischentext"  
      ...  
      $offset = $treffer[1][1] + strlen( $treffer[1][0] );  
    // ende_der_schleife  
    
    

    Die erste Klammer enthält ein gewöhnliches Suchmuster und umgeht so das
    (eventuell auftretende) Problem mit Lookbehind-Assertions, die in
    PHPs-PCRE derzeit nur feste Längen haben dürfen.

    Wie gehe ich dabei am besten vor? Mit regulären Ausdrücken?

    Am liebsten zerlege ich solche Meta-Daten-Listen mit preg_split().
    Allerdings sollte der Text dazu "strukturierter" aufgebaut sein.

    Wenn dein Text wirklich so unstrukturiert aufgebaut ist, dann kommst du
    mit einem einzelnem RegEx wahrscheinlich nicht sehr weit. Das einzige
    Muster, was ich hier sehe, ist der Zeilenumbruch. Prinzipiell könnte man
    den Text zuerst mit
    $zeilen = preg_split('/(\r\n|[\r\n])/', $dein_text);
    in einzelne Zeilen zerlegen.

    Danach wirds aber schwierig, da es kein einheitliches Trennzeichen (und
    auch keine einheitliche Trennzeichenfolge) zwischen den "Bezeichnern" und
    den folgenden Daten gibt. Wenn es das gäbe, könntest du einfach nochmal mit
    preg_split() drübergehen. Aber so musst du für jede Zeile ein eigenes Muster
    finden.

    Beispiele:

      
    // Driver: GTiff/GeoTIFF  
    list($k, $v) = preg_split('/:/', $zeile, 2);  
    // Size is 6400, 9600  
    list($k, $v) = preg_split('/(?<is)\s+/', $zeile, 2);  
    // Pixel Size = (10.00000000,-10.00000000)  
    list($k, $v) = preg_split('/\s+=\s+/', $zeile, 2);  
    
    

    Wenn du die Metadaten selbst aus den Bilddateien rausholst, könntest du
    auch eine Ebene tiefer ansetzen, anstatt den formatierten Text zu zerlegen,
    der ja selbst aus den Metadaten gewonnen wurde.

    MffG
    EisFuX

    1. Hello,

      [...]

      Nun möchte ich immer die Metainformationen zwischen zwei Ausdrücken extrahieren.

      [...]

      Hierzu würde ich preg_match() etwa so einsetzen:

      [...]

      Danach wirds aber schwierig, da es kein einheitliches Trennzeichen (und

      Wenn ich mich nicht total irre, dann werden solche Metadaten-Header als Blockheader geschreiben, also mit fester Feldlänge erstellt.

      Bevor man hier mit RegExen beginnt, sollt man vielleicht mal die Dateispezifikation zu Rate ziehen, ob ich richtig liege. Dann braucht man nämlich nur ein substr() und das Wissen über Position und Länge und den Zieltyp für jedes Datenfeld.

      Alternativ könnte man auch mal mehrere Header aus mehreren untereschiedlichen Dateien vergleichen.

      Ich sag hier nur eins "nicht ohne meinen Hexdump-Editor"

      Harzliche Grüße vom Berg
      http://bergpost.annerschbarrich.de

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      Nur selber lernen macht schlau
      Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

      1. (Hallo|Hi(ho)|Tag) Tom,

        Wenn ich mich nicht total irre, dann werden solche Metadaten-Header als Blockheader geschreiben, also mit fester Feldlänge erstellt.

        Hmm, ich dachte hier eher an diverse APP-Segmente in J(F)IF-Dateien oder dadrin nochmal das EXIF-Zeugs ...

        Bevor man hier mit RegExen beginnt, sollt man vielleicht mal die Dateispezifikation zu Rate ziehen, ob ich richtig liege. Dann braucht man nämlich nur ein substr() und das Wissen über Position und Länge und den Zieltyp für jedes Datenfeld.

        PHP hat von Perl auch unpack() geerbt.
        Das gibt zwar etwas wunderliche Arrays zurück, gefällt mir aber besser als herum-"peeken" mit substr().

        Alternativ könnte man auch mal mehrere Header aus mehreren untereschiedlichen Dateien vergleichen.

        Wenn jede Datei die gleichen Meta-Bezeichner liefert.
        Gerade beim oben erwähnten JIF und EXIF gibts ja auch optionale Felder.

        Ich sag hier nur eins "nicht ohne meinen Hexdump-Editor"

        Bei EXIF könntest du als menschlicher Betrachter aber allenfalls noch die Byte-Order ("MM" oder "II") erkennen ...
        ;-)

        MffG
        EisFuX

        1. Hello,

          PHP hat von Perl auch unpack() geerbt.

          Das finde ich eklig. Wann die PHP-DEVs wohl mal endlich selbstdefinierte Strukturen zulassen, soe wie in Pascal (record) oder C (struct)? Das hat man früher nicht impelmentiert, weil ja "das Web" Textdatei-orientiert ist, aber man muss doch zugeben, dass PHP heutzutage immer mehr in Bereichen auftaucht, wo auch "vernünftige Binärdeteien" an der Tagesordnung sind.

          Das gibt zwar etwas wunderliche Arrays zurück, gefällt mir aber besser als herum-"peeken" mit substr().

          Der Ausdruck "peeken" erinnert mich so an Basic.

          Bei EXIF könntest du als menschlicher Betrachter aber allenfalls noch die Byte-Order ("MM" oder "II") erkennen ...
          ;-)

          Das wäre natürlich ein wenig wenig. Ohne Dateibeschreibung wird man da wohl recht lange brauchen, um Zusammenhänge herauszufinden. Und dann noch diese lästige Intel-Notation...

          Harzliche Grüße vom Berg
          http://bergpost.annerschbarrich.de

          Tom

          --
          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
          Nur selber lernen macht schlau
          Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)