Parenthèses non capturantes dans les regex PHP
Les parenthèses () remplissent deux fonctions -
le regroupement de caractères et la fonction de capture (groupe de capture).
Mais que faire si nous avons besoin de regrouper,
sans pour autant capturer ?
Pour résoudre ce problème, des
parenthèses non capturantes spéciales (?: )
ont été inventées - elles regroupent, mais ne capturent pas.
Exemple
Dans l'exemple suivant, les premières parenthèses nous sont nécessaires pour le regroupement, et les secondes - pour la capture. Cependant, les deux types de parenthèses capturent les données dans un groupe de capture :
<?php
$str = 'abab123';
$reg = '#(ab)+([1-9]+)#';
preg_match_all($reg, $str, $res);
?>
En conséquence, nos groupes de capture contiendront ce qui suit :
<?php
var_dump($res[0]); // affichera 'abab123'
var_dump($res[1]); // affichera 'ab'
var_dump($res[2]); // affichera '123'
?>
Exemple
Faisons en sorte que la première paire de parenthèses seulement regroupe, sans capturer :
<?php
$str = 'abab123';
$reg = '#(?:ab)+([1-9]+)#';
preg_match_all($reg, $str, $res);
?>
En conséquence, notre nombre sera dans le premier groupe de capture :
<?php
var_dump($res[1]); // affichera '123'
?>
Tâches pratiques
Étant données des sous-chaînes, divisées en deux parties
par un nombre arbitraire de paires de $@ :
<?php
$str = 'aaa$@bbb aaa$@$@bbb aaa$@$@$@bbb';
?>
Trouvez chacune de ces sous-chaînes et pour chaque sous-chaîne trouvée, placez dans le premier groupe de capture ce qui se trouve avant le séparateur, et dans le deuxième groupe de capture - ce qui se trouve après le séparateur.