$re = '/^(?: # non-capture group (repeat)
(?| # branch reset for group 1
([^)(><\n])| # either non-bracket... or:
<(?=.*(>))| # if < open angle capture > to group 1
>(?=.*(<))| # if > capture opening < to group 1
\((?=.*(\)))| # same for (), if ( capture ) to group 1
\)(?=.*(\()) # if ) catpure ( to group 1
)(?=.*((?(2)\1\2|\1))$) # cond (2): if not outer chr (fwd ref)
)*? # as few as possible (lazy) / eof non-cap
[^)(><\n]? # the middle character (no parens)
\2$ # the right part (group 2 capture)/mx';
$str = '(_)tar<>rat(_)
)()_<(*&bab&*)>_()(
)(*?*)(
()<_<oxxo>_>()
<__>w(owiwo)w<__>
a(t<()((<oyo>))()>t)a
v
(_)tar<>rap(_)
)()_<(*&bab&*)>_))(
)(*?*)(.
()<-<oxxo>_>()
<__>w(ow(wo)w<__>
at<()((<oyo>))()>t)a';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
// Print the entire match result
var_dump($matches);
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for PHP, please visit: http://php.net/manual/en/ref.pcre.php