Captures dans les expressions régulières en PHP
Le contenu des captures est accessible non seulement dans la chaîne de remplacement, mais aussi dans l'expression régulière elle-même : nous pouvons mettre quelque chose dans une capture, puis dire directement dans l'expression régulière que le contenu de cette capture doit se trouver ici.
Le contenu des captures est accessible par leurs numéros,
précédés d'un antislash. Par exemple,
la capture zéro sera accessible comme ceci : \0,
la première capture comme ceci - \1, la deuxième
- \2 et ainsi de suite.
Je suis sûr que tout ce qui est écrit ci-dessus est encore très flou pour vous. Ce n'est pas étonnant, car les captures sont l'aspect le plus difficile à comprendre des expressions régulières. Analysons cela avec des exemples.
Exemple
Supposons que nous ayons la chaîne suivante :
<?php
$str = 'aa bb cd ef';
?>
Trouvons tous les endroits où deux lettres identiques se suivent. Pour résoudre le problème, nous chercherons n'importe quelle lettre, nous la mettrons dans une capture, puis nous vérifierons si le caractère suivant correspond au contenu de cette capture :
<?php
$res = preg_replace('#([a-z])\1#', '!', $str);
?>
En conséquence, la variable contiendra ce qui suit :
'! ! cd ef'
Exemple
Supposons que nous ayons la chaîne suivante :
<?php
$str = 'asxca buzxb csgd';
?>
Trouvons tous les mots dont la première et la dernière lettre sont identiques. Pour résoudre le problème, nous écrirons le modèle suivant : une lettre, puis une ou plusieurs lettres supplémentaires, puis la même lettre que la première :
<?php
$res = preg_replace('#([a-z])[a-z]+\1#', '!', $str);
?>
En conséquence, la variable contiendra ce qui suit :
'! ! csgd'
Exemple
Au lieu de \1, on peut écrire \g1 :
<?php
$res = preg_replace('#([a-z])[a-z]+\g1#', '!', $str);
?>
Exemple
On peut aussi écrire \g{1} :
<?php
$res = preg_replace('#([a-z])[a-z]+\g{1}#', '!', $str);
?>
Exemple
Dans les accolades, on peut spécifier des nombres négatifs. Dans ce cas, les captures seront comptées à partir de la fin :
<?php
$res = preg_replace('#([a-z])([a-z])\g{-2}#', '!', $str);
?>
Tâches pratiques
Soit la chaîne :
<?php
$str = 'aaa bbb ccc xyz';
?>
Trouvez toutes les sous-chaînes où trois lettres identiques se suivent.
Soit la chaîne :
<?php
$str = 'a aa aaa abab bbbb';
?>
Trouvez toutes les sous-chaînes où deux lettres identiques ou plus se suivent.
Soit la chaîne :
<?php
$str = 'aaa aaa bbb bbb ccc ddd';
?>
Trouvez toutes les sous-chaînes où deux mots identiques se suivent.