Pakeitimas su atgaliniu kvietimu naudojant reguliariąsias išraiškas PHP
Tarkime, kad turime tokią eilutę:
<?php
$str = '2+3= 3+5= 7+8=';
?>
Tarkime, mums reikia rasti visas konstrukcijas, pavidalo skaičius+skaičius= ir padaryti taip, kad po lygybės ženklo atsirastų sudėties rezultatas.
Norint išspręsti tokią užduotį, patogu naudoti
funkciją preg_replace_callback, kuri
veikia analogiškai funkcijai preg_replace
- randa ir pakeičia pagal reguliąją išraišką,
bet leidžia atlikti papildomus veiksmus
su rastomis dalimis.
Pirmuoju parametru funkcija priima reguliąją išraišką, antruoju - į ką keičiame, trečiuoju - eilutę, kurioje atliekamas pakeitimas.
Be to, antruoju parametru reikia perduoti funkciją-atgalinį-kvietimą, kuri bus iškviesta kiekvienam rastam atitikmeniui.
Pirmuoju atgalinio kvietimo parametru reikia nurodyti kintamąjį, į kurį pateks rasta dalis. Šis kintamasis bus masyvas rastų "kišenių" (angl. capture groups).
Pabandykime praktiškai. Parašykime kodą, kuris pagaus mūsų poeilutes, tuo pačiu įdėdamas pirmą skaičių į pirmą "kišenę", o antrajį - į antrą:
<?php
$str = '2+3= 3+5= 7+8=';
preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
var_dump($match);
}, $str);
?>
Dėl to mūsų var_dump suveiks
tris kartus, paeiliui išvesdamas tai:
['2+3=', '2', '3']
['3+5=', '3', '5']
['7+8=', '7', '7']
Toliau. Kiekvienas atitikmuo bus pakeistas
tuo, ką atgalinis kvietimas grąžina per return.
Pavyzdžiui, pakeiskime kiekvieną ieškomą
poeilutę ženklu '!':
<?php
$str = '2+3= 3+5= 7+8=';
$res = preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
return '!';
}, $str);
echo $res; // išves '! ! !'
?>
O dabar pakeiskime kiekvieną poeilutę į skaičių poros joje sumą:
<?php
$str = '2+3= 3+5= 7+8=';
$res = preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
return $match[1] + $match[2];
}, $str);
echo $res; // išves '5 8 13'
?>
Pasirodo, kad mūsų užduotis beveik išspręsta. Beliko pasidaryti taip, kad prieš sumą liktų ieškoma poeilutė. Tam įstatysime prieš sumą nulinei "kišenei" priklausančią reikšmę:
<?php
$str = '2+3= 3+5= 7+8=';
$res = preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
return $match[0] . ($match[1] + $match[2]);
}, $str);
echo $res; // išves '2+3=5 3+5=8 7+8=13'
?>
Duota eilutė:
<?php
$str = 'The numbers are 3, 7 and 12';
?>
Pakeiskite visus eilutės skaičius jų kvadratais.
Tikimasis rezultatas:
'The numbers are 9, 49 and 144'
Duota eilutė:
<?php
$str = '2023-01-15 2022-12-31 2024-05-20';
?>
Paverskite visas datas į formatą diena.mėnuo.metai.
Duota eilutė:
<?php
$str = 'Costs: $15, $20, $100';
?>
Padidinkite visas kainas 10%.