การจำกัดความละโมบในนิพจน์ปกติของ PHP
โดยค่าเริ่มต้น นิพจน์ปกติจะมี ความละโมบ ซึ่งหมายความว่าพวกมันจะจับตัวอักษรจำนวนมากที่สุดเท่าที่เป็นไปได้
ลองมาดูตัวอย่างกัน สมมติว่าเรามีสตริงดังนี้:
<?php
$str = 'aeeex zzz x kkk';
?>
สมมติว่าในสตริงนี้เราต้องการค้นหาสตริงย่อย
'aeeex' โดยใช้รูปแบบดังนี้: ตัวอักษร
'a' ตามด้วยอักขระใดๆ หนึ่งตัวหรือมากกว่า
จากนั้นตามด้วยตัวอักษร 'x'
<?php
$res = preg_replace('#a.+x#', '!', $str);
?>
เราคาดหวังว่าในตัวแปร $res จะเก็บสตริง
'! zzz x kkk' อย่างไรก็ตาม ไม่เป็นเช่นนั้น -
ตัวแปรกลับเก็บสตริง '! kkk'
สาเหตุทั้งหมดอยู่ที่ว่านิพจน์ปกติของเราค้นหาทุก
ตัวอักษรจากตัวอักษร 'a' ไปจนถึงตัวอักษร 'x'
แต่ในสตริงของเรามีตัวอักษร 'x' อยู่สองตัว เนื่องจาก
ความละโมบจึงทำให้นิพจน์ปกติค้นหาไปจนถึง
ตัว 'x' สุดท้าย ทำให้จับส่วนที่เราไม่ได้คาดหวังไว้
แน่นอนว่าในหลายกรณีพฤติกรรมนี้เป็นสิ่งที่เราต้องการ
แต่ในกรณีนี้โดยเฉพาะ เราอยากยกเลิกความละโมบ
และบอกนิพจน์ปกติให้ค้นหาไปจนถึงตัว 'x' ตัวแรก
เพื่อจำกัดความละโมบ จำเป็นต้องใส่เครื่องหมายคำถาม หลังโอเปอเรเตอร์การทำซ้ำ:
<?php
$res = preg_replace('#a.+?x#', '!', $str);
?>
สามารถจำกัดความละโมบให้กับโอเปอเรเตอร์การทำซ้ำทั้งหมดได้
ดังนี้: *?, ??
และ {}?
กำหนดสตริง:
<?php
$str = 'aba accca azzza wwwwa';
?>
เขียนนิพจน์ปกติที่ค้นหาสตริงทั้งหมด
ซึ่งมีตัวอักษร 'a' อยู่ที่ขอบทั้งสองด้าน
และแทนที่แต่ละสตริงด้วย '!' ระหว่าง
ตัวอักษร a สามารถเป็นอักขระใดๆ ก็ได้ (ยกเว้น
ตัวอักษร 'a')