In Perl zijn kwantificatoren in reguliere expressies — *, +, ?, {n,m} — standaard hebzuchtig (greedy): ze nemen het maximaal mogelijke aantal karakters dat overeenkomt met het patroon.
Het toevoegen van ? na de kwantificator verandert deze in luie (lazy of non-greedy): hij neemt het minimaal mogelijke aantal karakters zodat de gehele reguliere expressie overeenkomt.
my $str = 'foo <bar> baz <quux>'; $str =~ /<.*>/; # Neemt '<bar> baz <quux>'
my $str = 'foo <bar> baz <quux>'; $str =~ /<.*?>/; # Neemt '<bar>'
Een hebzuchtige expressie kan "meer eten" dan je verwacht bij het parseren van HTML en andere geneste constructies!
Wat is het verschil tussen de volgende twee reguliere expressies bij het analyseren van de string
<a><b><c>:/<(.*)>/en/<(.*?)>/?
Antwoord:
/<(.*)>/ (hebzuchtig) neemt het maximale blok — match: <a><b><c>/<(.*?)>/ (luie) — alleen de eerste groep: <a>Voorbeeld:
my $s = '<a><b><c>'; $s =~ /<(.*)>/; # $1: 'a><b><c' $s =~ /<(.*?)>/; # $1: 'a'
Verhaal
In een applicatie voor het importeren van nieuwsheadlines wilde een programmeur de tagnaam extraheren uit de string
<title>Nieuws</title>, met behulp van/\<(.*)\>/. Uiteindelijk nam de reguliere expressie de hele string tussen de eerste<en de laatste>, in plaats van het gewenste element. De fout werd ontdekt toen geneste tags verschenen.
Verhaal
In een logische parser voor het extraheren van quoted strings nam het gebruikte patroon
/"(.*)"/onverwacht alles tussen de eerste en laatste aanhalingstekens. Dit resulteerde in een onjuiste markering totdat het patroon werd vervangen door/"(.*?)"/.
Verhaal
In een automatische CSV-parser met quotes was het patroon ten onrechte geschreven voor "hebzucht", waardoor meerdere kolommen aan elkaar werden geplakt. De fout van de ingevoerde parser kwam pas naar voren bij grote datasets — een luie modificatie van het patroon loste het probleem op.