PHPда регуляр ифодаларнинг ҳаддан ташқари ҳаракатларини чеклаш
Регуляр ифодалар сустки холда ҳадим бўлади. Бу улар максимал имконият бўлган белгиларни олиб олишларини англатади.
Келинг, мисол билан кўриб чиқайлик. Фарз қилайлик, бизда мана бундай сатр бор:
<?php
$str = 'aeeex zzz x kkk';
?>
Фарз қилайлик, биз бу сатрда
'aeeex' қисм сатрни топишни истаймиз
куйидаги намуна бўйича: ҳарф
'a', сўнгра бир ёки бир неча марта ҳар қандай белги,
сўнгра ҳарф 'x'.
<?php
$res = preg_replace('#a.+x#', '!', $str);
?>
Биз натижада ўзгарувчига
'! 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' дан ташқари).