In Perl sind die Quantifizierer in regulären Ausdrücken – *, +, ?, {n,m} – standardmäßig gierig (greedy): sie erfassen die maximal mögliche Anzahl von Zeichen, die dem Muster entsprechen.
Das Hinzufügen von ? nach dem Quantifizierer verwandelt ihn in faul (lazy oder non-greedy): er erfasst die minimal mögliche Anzahl von Zeichen, damit das gesamte reguläre Ausdruck übereinstimmt.
my $str = 'foo <bar> baz <quux>'; $str =~ /<.*>/; # Erfasst '<bar> baz <quux>'
my $str = 'foo <bar> baz <quux>'; $str =~ /<.*?>/; # Erfasst '<bar>'
Ein gieriger Ausdruck kann "mehr fressen" als erwartet beim Parsen von HTML und anderen verschachtelten Konstruktionen!
Wie unterscheiden sich die folgenden beiden regulären Ausdrücke beim Parsen der Zeichenfolge
<a><b><c>:/<(.*)>/und/<(.*?)>/?
Antwort:
/<(.*)>/ (gierig) erfasst den maximalen Block – Übereinstimmung: <a><b><c>/<(.*?)>/ (faul) – nur die erste Gruppe: <a>Beispiel:
my $s = '<a><b><c>'; $s =~ /<(.*)>/; # $1: 'a><b><c' $s =~ /<(.*?)>/; # $1: 'a'
Geschichte
In einer Anwendung zum Importieren von Nachrichtenüberschriften wollte der Programmierer den Tag-Namen aus der Zeichenfolge
<title>Nachricht</title>parsen, indem er/\<(.*)\>/verwendete. Am Ende erfasste die reguläre Ausdruck die gesamte Zeichenfolge zwischen<dem ersten und>dem letzten, statt dem gewünschten Element. Der Fehler wurde gefunden, als verschachtelte Tags auftauchten.
Geschichte
In einem logischen Parser zur Extraktion von zitierten Zeichenfolgen erfasste das verwendete Muster
/"(.*)"/unerwartet alles zwischen dem ersten und dem letzten Anführungszeichen. Infolgedessen wurde die Markierung nicht korrekt aufgeteilt, bis das Muster durch/"(.*?)"/ersetzt wurde.
Geschichte
In einem automatisierten CSV-Parser mit Anführungszeichen wurde das Muster "gierig" falsch geschrieben, wodurch mehrere Spalten zu einer einzigen zusammengeklebt wurden. Der Fehler im Parser trat erst bei großen Datenmengen auf – die faule Modifikation des Musters löste das Problem.