Menghadkan Ketamakan dalam Regex di PHP
Ungkapan biasa secara lalai adalah greedy. Ini bermakna mereka akan menangkap aksara sebanyak mungkin.
Mari kita lihat contoh. Katakan kita mempunyai tali seperti berikut:
<?php
$str = 'aeeex zzz x kkk';
?>
Katakan dalam tali ini, kita mahu mencari subrentetan
'aeeex' berdasarkan corak berikut: huruf
'a', diikuti oleh sebarang aksara satu atau lebih
kali, kemudian huruf 'x'.
<?php
$res = preg_replace('#a.+x#', '!', $str);
?>
Kami menjangkakan bahawa hasilnya dalam pembolehubah
akan menjadi tali '! zzz x kkk'. Walau bagaimanapun,
ianya tidak begitu - pembolehubah tersebut mengandungi tali
'! kkk'.
Ini berlaku kerana regex kami mencari semua
aksara dari huruf 'a' hingga huruf 'x'.
Tetapi dalam tali kami terdapat dua huruf 'x'. Disebabkan
sifat tamak, regex akan mencari sehingga
huruf 'x' yang terakhir, sekali gus menangkap
lebih daripada yang kita jangkakan.
Sudah tentu, selalunya tingkah laku ini adalah yang kita mahukan. Tetapi khusus dalam kes ini, kita ingin membatalkan sifat tamak dan memberitahu regex untuk berhenti mencari pada huruf 'x' yang pertama.
Untuk menghadkan ketamakan, letakkan tanda tanya selepas operator pengulangan:
<?php
$res = preg_replace('#a.+?x#', '!', $str);
?>
Ketamakan boleh dihadkan untuk semua operator
pengulangan, seperti berikut: *?, ??
dan {}?.
Diberi tali:
<?php
$str = 'aba accca azzza wwwwa';
?>
Tulis regex yang akan mencari semua rentetan
yang diapit oleh huruf 'a',
dan menggantikan setiap satu daripadanya dengan '!'. Antara
huruf a tersebut boleh terdapat sebarang aksara (selain
'a').