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<?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<?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<?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<?php
  var_dump($res[1]); // affichera '123'
?>

Tâches pratiques

Задание 1

Étant données des sous-chaînes, divisées en deux parties par un nombre arbitraire de paires de $@ :

php<?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.