Nahradzanie s callbackom cez regulárne výrazy v PHP
Majme nasledujúci reťazec:
<?php
$str = '2+3= 3+5= 7+8=';
?>
Predpokladajme, že potrebujeme nájsť všetky konštrukcie typu číslo+číslo= a zabezpečiť, aby sa po znamienku rovná sa objavil výsledok sčítania.
Na riešenie podobnej úlohy je vhodné použiť
funkciu preg_replace_callback, ktorá
funguje analogicky ako funkcia preg_replace
- nájde a nahradí podľa regulárneho výrazu,
ale umožňuje vykonávať dodatočné manipulácie
s nájdenými časťami.
Prvým parametrom funkcia prijíma regulárny výraz, druhým - na čo nahradiť, tretím - reťazec, v ktorom sa vykonáva nahradzovanie.
Pričom do druhého parametra by sa mala odovzdať funkcia-callback, ktorá bude volaná pre každý nájdený výskyt.
Ako prvý parametra callbacku je potrebné uviesť premennú, do ktorej sa bude ukladať nájdený výskyt. Táto premenná bude predstavovať pole zachytených skupín (capturing groups) nájdeného výrazu.
Vyskúšajme si to v praxi. Napíšme kód, ktorý zachytí naše podreťazce, pričom prvé číslo uloží do prvej skupiny, a druhé - do druhej:
<?php
$str = '2+3= 3+5= 7+8=';
preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
var_dump($match);
}, $str);
?>
V dôsledku toho náš var_dump zbehne
trikrát a postupne vypíše nasledovné:
['2+3=', '2', '3']
['3+5=', '3', '5']
['7+8=', '7', '7']
Pokračujme. Každý nájdený výskyt bude nahradený
tým, čo vráti callback pomocou return.
Pre príklad nahraďme každý hľadaný
podreťazec znakom '!':
<?php
$str = '2+3= 3+5= 7+8=';
$res = preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
return '!';
}, $str);
echo $res; // vypíše '! ! !'
?>
A teraz nahraďme každý podreťazec súčtom dvojice čísel v ňom:
<?php
$str = '2+3= 3+5= 7+8=';
$res = preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
return $match[1] + $match[2];
}, $str);
echo $res; // vypíše '5 8 13'
?>
Vychádza, že naša úloha je takmer vyriešená. Ostáva už len zabezpečiť, aby pred súčtom čísiel ostal pôvodný hľadaný podreťazec. Na to budeme vkladať pred súčet obsah nultej skupiny (celý nájdený výraz):
<?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; // vypíše '2+3=5 3+5=8 7+8=13'
?>
Daný reťazec:
<?php
$str = 'The numbers are 3, 7 and 12';
?>
Nahraďte všetky čísla v reťazci ich druhými mocninami (štvorcami).
Očakávaný výsledok:
'The numbers are 9, 49 and 144'
Daný reťazec:
<?php
$str = '2023-01-15 2022-12-31 2024-05-20';
?>
Preveďte všetky dátumy do formátu deň.mesiac.rok.
Daný reťazec:
<?php
$str = 'Costs: $15, $20, $100';
?>
Zvýšte všetky ceny o 10%.