Das folgende Beispiel entstammt einer kleinen dateibasierten Bildergalerie. Dort werden das Jahr und die Abmessungen, beide Angaben optional, direkt
im Dateinamen kodiert.
Die Zerlegung in die Einzelinformationen erfolgt mit Hilfe eines regulären Ausdrucks.
Da der Titel des Bildes selbst beliebige Zeichen enthalten kann ist die Formulierung eines passenden Musters schwierig.
Sehr viel einfacher lässt sich die Aufgabe lösen wenn der String mit strrev() temporär umgedreht wird.
Hier kommt der x-Modifier zum Einsatz um das etwas umfangreichere Muster kommentieren zu können.
<?php
// Beispiele fuer Dateinamen ...
$sample_list = array();
$sample_list[] = 'Ein Bildchen.jpg';
$sample_list[] = 'Variation 1 2005.jpg';
$sample_list[] = 'Variation 3 2006 150x150.Jpg';
$sample_list[] = '1 x 1 ist 1 250x250.JPG';
$sample_list[] = 'Hirsch in Oel 2006 150x150.jpeg';
$sample_list[] = 'Das Picknick 2006 350_250.jpg';
$sample_list[] = 'Kein JPG.png'; # das hier faellt durch
$sample_list[] = '123 2008 3501X4000.jpg';
$sample_list[] = '1984.jpg';
$sample_list[] = '1984 2001.jpg';
// Standardvorgaben, diese werden dann mit den ermittelten Informationen kombiniert
$default_list = array('title' => 'Ohne Titel', 'dimensions' => 'unbekannt', 'year' => 'unbekannt');
foreach ($sample_list as $sample){
// hier wird der String umgedreht, damit kann man im Suchmuster die optionalen Bestandteile leichter formulieren
$tmp = strrev($sample);
$success = preg_match(
'/ #Delimiter
^ge?pj\. # Dateiendung
(?<dimensions>[\d]+[x_][\d]+)? # optionale Angabe der Abmessungen
\s* # optionaler Whitespace
(?<year>[\d]{4})? # optionale Angabe des Jahres
\s* # optionaler Whitespace
(?<title>.+) # Titel des Bildes
$/ix',
$tmp,
$match_list
);
if (!$success){
printf('<h2 style="color:#c00;">Bei <em>%s</em> versagte das Muster</h2>', htmlentities($sample));
continue;
}
// hier die Umkehrung des Strings fuer alle Elemente wieder rueckgaengig machen ...
$match_list = array_map( 'strrev', $match_list);
// um nummerische Elemente reduzieren, hier interessieren nur die "named subpattern" ...
$match_list = array_intersect_key($match_list, $default_list);
// leere Elemente ausfiltern ...
$match_list = array_filter($match_list);
// verbleibendes Ergebnis mit den Standardwerten kombinieren ...
$match_list = array_merge($default_list, $match_list );
printf ('<h2>%s</h2>', htmlentities($sample));
printf ('<dl><dt>Titel</dt><dd>%s</dd><dt>Abmessungen</dt><dd>%s</dd><dt>Jahr</dt><dd>%s</dd></dl>', $match_list['title'], $match_list['dimensions'],$match_list['year']);
}
?>