Substituição com Callback usando Expressões Regulares em PHP

Suponha que temos a seguinte string:

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

Suponha que precisamos encontrar todas as construções do tipo número+número= e fazer com que após o igual apareça o resultado da soma.

Para resolver este tipo de problema, é conveniente usar a função preg_replace_callback, que funciona de forma análoga à função preg_replace - encontra e substitui por uma expressão regular, mas permite realizar manipulações adicionais com os trechos encontrados.

O primeiro parâmetro da função é a expressão regular, o segundo - pelo que substituir, o terceiro - a string na qual a substituição é realizada.

Neste caso, no segundo parâmetro deve ser passada uma função de callback, que será chamada para cada correspondência encontrada.

O primeiro parâmetro do callback deve ser uma variável, na qual será colocada a correspondência. Esta variável será um array com os grupos de captura (capturas) encontrados.

Vamos tentar na prática. Escreveremos um código que capturará nossas substrings, colocando o primeiro número no primeiro grupo e o segundo - no segundo grupo:

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

Como resultado, nosso var_dump será executado três vezes, exibindo sequencialmente o seguinte:

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

Vamos em frente. Cada correspondência será substituída pelo que o callback retornar via return. Vamos, por exemplo, substituir cada uma das substrings procuradas pelo sinal '!':

php<?php
  $str = '2+3= 3+5= 7+8=';
  
  $res = preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
    return '!';
  }, $str);
  
  echo $res; // exibirá '! ! !'
?>

E agora vamos substituir cada substring pela soma do par de números nela:

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; // exibirá '5 8 13'
?>

Ou seja, nossa tarefa está quase resolvida. Só falta fazer com que antes da soma dos números a substring original permaneça. Para isso inseriremos antes da soma o conteúdo do grupo zero (a correspondência completa):

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

Dada a string:

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

Substitua todos os números na string pelos seus quadrados.

Resultado esperado:

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

Dada a string:

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

Converta todas as datas para o formato dia.mês.ano.

Задание 3

Dada a string:

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

Aumente todos os preços em 10%.