Kalamari
Kalamari

Reputation: 33

Regex pattern explanation

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

Answers (2)

brian d foy
brian d foy

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

FailedDev
FailedDev

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

Related Questions