Замена са колбеком преко регуларних израза у PHP

Претпоставимо да имамо следећи стринг:

php<?php
  $str = '2+3= 3+5= 7+8=';
?>

Претпоставимо да треба да пронађемо све конструкције облика број+број= и да учинимо да се после једнако појави резултат сабирања.

За решавање сличног проблема погодно је користити функцију preg_replace_callback, која ради аналогно функцији preg_replace - проналази и замењује према регуларном изразу, али омогућава извођење додатних манипулација са пронађеним деловима.

Први параметар функција прима регуларни израз, други - на шта мењамо, трећи - стринг, у коме се врши замена.

При томе у други параметар треба проследити функцију-колбек, која ће бити позвана за свако пронађено поклапање.

Првим параметром колбека треба навести променљиву у коју ће упадати пронађено. Та променљива ће представљати низ кармана пронађеног.

Хајде да испробамо у пракси. Написаћемо, код, који ће ухватити наше подстрингове, при томе стављајући први број у први карман, а други - у други:

php<?php
  $str = '2+3= 3+5= 7+8=';
  
  preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
    var_dump($match);
  }, $str);
?>

Као резултат, наш var_dump ће радити три пута, заузast редом исписујући следеће:

php['2+3=', '2', '3']
['3+5=', '3', '5']
['7+8=', '7', '7']

Идемо даље. Свако поклапање ће бити замењено оним што колбек враћа преко return. Хајде за пример да заменимо сваки од тражених подстрингова знаком '!':

php<?php
  $str = '2+3= 3+5= 7+8=';
  
  $res = preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
    return '!';
  }, $str);
  
  echo $res; // исписаће '! ! !'
?>

А сада заменимо сваки подстринг збиром пара бројева у њему:

php<?php
  $str = '2+3= 3+5= 7+8=';
  
  $res = preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
    return $match[1] + $match[2];
  }, $str);
  
  echo $res; // исписаће '5 8 13'
?>

Добија се да је наш задатак скоро решен. Остаје да учинимо да се пред збиром бројева задржи тражени подстринг. За то ћемо уметнути пред збир садржај нултог кармана:

php<?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; // исписаће '2+3=5 3+5=8 7+8=13'
?>
Задание 1

Дат је стринг:

php<?php
  $str = 'The numbers are 3, 7 and 12';
?>

Замените све бројеве у стрингу њиховим квадратима.

Очекивани резултат:

php'The numbers are 9, 49 and 144'
Задание 2

Дат је стринг:

php<?php
  $str = '2023-01-15 2022-12-31 2024-05-20';
?>

Преобразујте све датуме у формат дан.месец.година.

Задание 3

Дат је стринг:

php<?php
  $str = 'Costs: $15, $20, $100';
?>

Повећајте све цене за 10%.