Perl'de düzenli ifadelere uygulanan kuantifikatörler — *, +, ?, {n,m} — varsayılan olarak açgözlü (greedy): bunlar, desene uyan mümkün olan en fazla karakteri alırlar.
Kuantifikatörün sonuna ? eklemek onu tembel (lazy veya non-greedy) hale getirir: o, düzenli ifadenin tamamının eşleşmesi için mümkün olan en az karakteri alır.
my $str = 'foo <bar> baz <quux>'; $str =~ /<.*>/; # '<bar> baz <quux>' alır.
my $str = 'foo <bar> baz <quux>'; $str =~ /<.*?>/; # '<bar>' alır.
Açgözlü ifade, HTML ve diğer iç içe yapılar ayrıştırıldığında beklediğinizden daha fazla "yer" kaplayabilir!
<a><b><c>dizesini çözerken aşağıdaki iki düzenli ifade arasındaki fark nedir:/<(.*)>/ve/<(.*?)>/?
Cevap:
/<(.*)>/ (açgözlü) maksimum bloğu alır — eşleşme: <a><b><c>/<(.*?)>/ (tembel) — yalnızca ilk grubu: <a>Örnek:
my $s = '<a><b><c>'; $s =~ /<(.*)>/; # $1: 'a><b><c' $s =~ /<(.*?)>/; # $1: 'a'
Hikaye
Bir haber başlıkları içe aktarma uygulamasında programcı
<title>Haber</title>dizesindeki etiketin adını ayrıştırmak için/\<(.*)\>/kullandı. Sonuç olarak, düzenli ifade, ilk<ve son>arasında tüm dizeyi alıyordu, istenen öğeyi değil. Hata, iç içe etiketler ortaya çıktığında bulundu.
Hikaye
Bir mantıksel ayrıştırıcıda, quoted strings'i ayırmak için kullanılan şablon
/"(.*)"/beklenmedik bir şekilde ilk ve son tırnak arasında her şeyi alıyordu. Sonuç olarak, işaretleme yanlış bir şekilde bölündü, ta ki şablon/"(.*?)"/ile değiştirilene kadar.
Hikaye
Alıntılarla birlikte CSV'yi otomatik olarak ayıran bir ayrıştırıcıda şablon "açgözlülük" esasına göre yanlış yazılmıştı, bu yüzden birkaç sütun bir araya geldi. Girilen ayrıştırıcının hatası yalnızca büyük verilerde ortaya çıktı — şablonun tembel modifikasyonu sorunu çözdü.