String verarbeiten
Jo
- php
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
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
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
(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
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
(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
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