Icke-fångande parenteser i PHP regex

Parenteser () har två funktioner - gruppering av tecken och fångstfunktion. Men vad gör man om man vill gruppera, men inte fånga? För att lösa detta problem har speciella icke-fångande parenteser (?: ) skapats - de grupperar, men fångar inte.

Exempel

I följande exempel behöver vi den första parentesen för gruppering, och den andra - för fångst. Men båda parenteserna fångar data:

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

Som ett resultat kommer våra fångster att innehålla följande:

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

Exempel

Låt oss göra så att det första parentesparet endast grupperar, men inte fångar:

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

Som ett resultat kommer vårt nummer att finnas i den första fångsten:

php<?php
  var_dump($res[1]); // kommer att skriva ut '123'
?>

Praktiska uppgifter

Задание 1

Det finns delsträngar, uppdelade i två delar av ett godtyckligt antal par $@:

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

Hitta varje sådan delsträng och för varje hittad delsträng, lägg i den första fångsten vad som står före avgränsaren, och i den andra fångsten - vad som står efter avgränsaren.