A PCRE (recursive) pattern that matches a string containing the correct substring in brackets. Why is this failure?

Well, there are other ways (hmmm ... or rather, ways of working), but the question is, why is this failing?

/
\A              # start of the string
(               # group 1
(?:             # group 2
[^()]*          # something other than parentheses (greedy)
|               # or
\( (?1) \)      # parenthesized group 1
)               # -group 2
+               # at least once (greedy)
)               # -group 1
\Z              # end of the string
/x

Cannot match string with parentheses: "(())"

+3
source share
2 answers

Wow! .. Thanks, trash! It really works ... in Perl. But not in PCRE. So, the question mutates to "What is the difference between matching Perl regular expressions and PCRE?"

And voila! Answer:

The difference between recursion and Perl

 In PCRE (like Python, but unlike Perl), a recursive subpattern call  is
 always treated as an atomic group. That is, once it has matched some of
 the subject string, it is never re-entered, even if it contains untried
 alternatives  and  there  is a subsequent matching failure.

Therefore, we just need to change two subpatterns:

/ \A ( (?: \( (?1) \) | [^()]* )+ ) \Z /x

Thank!

+4
source

This will not work

$ perl junk.pl
matched junk >(())<

$ cat junk.pl
my $junk = qr/
\A              # start of the string
(               # group 1
(?:             # group 2
[^()]*          # something other than parentheses (greedy)
|               # or
\( (?1) \)      # parenthesized group 1
)               # -group 2
+               # at least once (greedy)
)               # -group 1
\Z              # end of the string
/x;

if( "(())" =~ $junk ){
    print "matched junk >$1<\n";
}
+7

Source: https://habr.com/ru/post/1748512/


All Articles