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
$str = 'abab123';
$reg = '#(ab)+([1-9]+)#';
preg_match_all($reg, $str, $res);
?>
W rezultacie w naszych kieszeniach będzie następująco:
<?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
$str = 'abab123';
$reg = '#(?:ab)+([1-9]+)#';
preg_match_all($reg, $str, $res);
?>
W rezultacie w pierwszej kieszeni będzie nasza liczba:
<?php
var_dump($res[1]); // wypisze '123'
?>
Zadania praktyczne
Dane są podciągi, oddzielone na dwie części
dowolną liczbą par $@:
<?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.