Niezachowujące nawiasy w regex PHP

Nawiasy () pełnią dwie funkcje - grupowanie znaków oraz funkcję kieszeni (capturing group). A co zrobić, jeśli potrzebujemy zgrupować, ale nie chcemy umieszczać w kieszeni? Aby rozwiązać ten problem, wymyślono specjalne niezachowujące nawiasy (?: ) - grupują one, ale nie umieszczają w kieszeni.

Przykład

W następnym przykładzie pierwsze nawiasy są nam potrzebne do grupowania, a drugie - do kieszeni. Jednakże, zarówno jedne, jak i drugie nawiasy zachowują dane do kieszeni:

php<?php
  $str = 'abab123';
  $reg = '#(ab)+([1-9]+)#';
  preg_match_all($reg, $str, $res);
?>

W rezultacie w naszych kieszeniach będzie następująco:

php<?php
  var_dump($res[0]); // wypisze 'abab123'
  var_dump($res[1]); // wypisze 'ab'
  var_dump($res[2]); // wypisze '123'
?>

Przykład

Sprawmy, aby pierwsza para nawiasów tylko grupowała, ale nie umieszczała w kieszeni:

php<?php
  $str = 'abab123';
  $reg = '#(?:ab)+([1-9]+)#';
  preg_match_all($reg, $str, $res);
?>

W rezultacie w pierwszej kieszeni będzie nasza liczba:

php<?php
  var_dump($res[1]); // wypisze '123'
?>

Zadania praktyczne

Задание 1

Dane są podciągi, oddzielone na dwie części dowolną liczbą par $@:

php<?php
  $str = 'aaa$@bbb aaa$@$@bbb aaa$@$@$@bbb';
?>

Znajdź każdy z takich podciągów i dla każdego znalezionego podciągu umieść w pierwszej kieszeni to, co znajduje się przed separatorem, a w drugiej kieszeni - to, co znajduje się za separatorem.