Reputation: 33
I am fairly new to regexes and I stubled upon a regex in perl script recently which I couldn't figure out:
$groups= qr/\(([^()]+|(??{$groups}))*\)/;
Any help would be appreciated!
Upvotes: 3
Views: 133
Reputation: 132792
The YAPE::Regex::Explain module can tell you what a regex is doing:
% perl5.14.2 -MYAPE::Regex::Explain -E 'say YAPE::Regex::Explain->new(shift)->explain' '\(([^()]+|(??{$groups}))*\)'
The regular expression:
(?-imsx:\(([^()]+|(??{$groups}))*\))
matches as follows:
NODE EXPLANATION
----------------------------------------------------------------------
(?-imsx: group, but do not capture (case-sensitive)
(with ^ and $ matching normally) (with . not
matching \n) (matching whitespace and #
normally):
----------------------------------------------------------------------
\( '('
----------------------------------------------------------------------
( group and capture to \1 (0 or more times
(matching the most amount possible)):
----------------------------------------------------------------------
[^()]+ any character except: '(', ')' (1 or
more times (matching the most amount
possible))
----------------------------------------------------------------------
| OR
----------------------------------------------------------------------
(??{$groups}) run this block of Perl code (that isn't
interpolated until RIGHT NOW)
----------------------------------------------------------------------
)* end of \1 (NOTE: because you are using a
quantifier on this capture, only the LAST
repetition of the captured pattern will be
stored in \1)
----------------------------------------------------------------------
\) ')'
----------------------------------------------------------------------
) end of grouping
----------------------------------------------------------------------
You can turn that one-liner into an alias in your profile:
alias re="perl -MYAPE::Regex::Explain -E 'say YAPE::Regex::Explain->new(shift)->explain'"
After that, you don't have to remember all that:
re '\(([^()]+|(??{$groups}))*\)'
Upvotes: 2
Reputation: 26930
Well if you expand it :
$groups= qr/
\( # match an open paren (
( # followed by
[^()]+ # one or more non-paren character
| # OR
(??{$groups}) # the regex itself
)* # repeated zero or more times
\) # followed by a close paren )
/x;
You get an elegant recursive approach to find balanced parentheses :)
Upvotes: 10