Remplacement par callback via des expressions régulières en PHP
Supposons que nous ayons la chaîne suivante :
<?php
$str = '2+3= 3+5= 7+8=';
?>
Supposons que nous devions trouver toutes les constructions de la forme nombre+nombre= et faire en sorte que le résultat de l'addition apparaisse après le signe égal.
Pour résoudre ce type de problème, il est pratique d'utiliser
la fonction preg_replace_callback, qui
fonctionne de manière analogue à la fonction preg_replace
- trouve et remplace via une expression régulière,
mais permet d'effectuer des manipulations supplémentaires
avec les fragments trouvés.
Le premier paramètre de la fonction accepte l'expression régulière, le deuxième - par quoi remplacer, le troisième - la chaîne dans laquelle le remplacement est effectué.
Dans le deuxième paramètre, il faut passer une fonction de callback, qui sera appelée pour chaque correspondance trouvée.
Le premier paramètre du callback doit être une variable dans laquelle la correspondance sera placée. Cette variable sera un tableau des groupes de capture (captures) trouvés.
Essayons en pratique. Écrivons le code qui capturera nos sous-chaînes, en plaçant le premier nombre dans le premier groupe, et le deuxième - dans le deuxième :
<?php
$str = '2+3= 3+5= 7+8=';
preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
var_dump($match);
}, $str);
?>
En conséquence, notre var_dump fonctionnera
trois fois, affichant successivement ce qui suit :
['2+3=', '2', '3']
['3+5=', '3', '5']
['7+8=', '7', '7']
Allons plus loin. Chaque correspondance sera remplacée
par ce que le callback retourne via return.
Prenons un exemple et remplaçons chaque sous-chaîne recherchée
par le signe '!' :
<?php
$str = '2+3= 3+5= 7+8=';
$res = preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
return '!';
}, $str);
echo $res; // affichera '! ! !'
?>
Et maintenant, remplaçons chaque sous-chaîne par la somme de la paire de nombres qu'elle contient :
<?php
$str = '2+3= 3+5= 7+8=';
$res = preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
return $match[1] + $match[2];
}, $str);
echo $res; // affichera '5 8 13'
?>
Il s'avère que notre tâche est presque résolue. Reste à faire en sorte qu'avant la somme des nombres, la sous-chaîne recherchée reste. Pour cela, nous allons insérer avant la somme le contenu du groupe zéro :
<?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; // affichera '2+3=5 3+5=8 7+8=13'
?>
Soit la chaîne :
<?php
$str = 'The numbers are 3, 7 and 12';
?>
Remplacez tous les nombres dans la chaîne par leurs carrés.
Résultat attendu :
'The numbers are 9, 49 and 144'
Soit la chaîne :
<?php
$str = '2023-01-15 2022-12-31 2024-05-20';
?>
Transformez toutes les dates au format jour.mois.année.
Soit la chaîne :
<?php
$str = 'Costs: $15, $20, $100';
?>
Augmentez tous les prix de 10%.