use strict;
my $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';
my $regex = qr/^(?: # 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)/mxp;
if ( $str =~ /$regex/g ) {
print "Whole match is ${^MATCH} and its start/end positions can be obtained via \$-[0] and \$+[0]\n";
# print "Capture Group 1 is $1 and its start/end positions can be obtained via \$-[1] and \$+[1]\n";
# print "Capture Group 2 is $2 ... and so on\n";
}
# ${^POSTMATCH} and ${^PREMATCH} are also available with the use of '/p'
# Named capture groups can be called via $+{name}
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 Perl, please visit: http://perldoc.perl.org/perlre.html