perl-diddler has asked for the wisdom of the Perl Monks concerning the following question:
Now I wanted to go to a pattern that matched a '{' opening brace followed or preceded by a balanced number of parenthesis.The following pattern matches a function foo() which may contain balanced parentheses as the argument. $re = qr{ ( # paren group 1 (full function) foo ( # paren group 2 (parens) \( ( # paren group 3 (contents of parens) (?: (?> [^()]+ ) # Non-parens without backtracking | (?2) # Recurse to start of paren group 2 )* ) \) ) ) }x;
I also discovered that the example doesn't handle backslashes or comment characters and I want mine to do so.
Well first get rid of '{' as the quote char cuz it's what i want to match. And since I wasn't using variables, single quote seemed logical. So I ended up with something like:
The comments at the top were broken attempts to allow chars at the beginning... then I noticed that inside single quotes, backslash only quotes backslash or a single quote. Yikes! So I got rid of the backslashes in the pattern that were quoting literals.#!/bin/perl -w use strict; #(?:[^{}#]|(?:\\).)* #(?: (?:\{2}+) (?:[^{}#]* | (?:\\.)) )* my $re = qr'^ ( { ( { ( (?: (?> [^{}]+ ) | (?2) )* ) } )*$ ) 'x; while (<>) { printf "%s\n", m{$re} ? "match" : "nomatch"; /^q/ && exit; }
The above seems to work with a a single opening brace followed by some number of matching braces with optional content. It ignores backslashes and comments as significant.
It also doesn't handle an even number of braces BEFORE the matching opening brace -- which is where I was looking next. To do so, I was going to emulate the recursive (?2) matching the 2nd capture expression... but realized as soon as I introduced more captures before my literal '{', that number 2 would change. Aeeii.. Named captures... what a cool idea... they won't change... seemed straight forward enough...so my re became:
But it doesn't work. It worked for a simple match + single nesting, like:my $re = qr'^ ( { (?<R> { ( (?: (?> [^{}]+ ) | (\q<R>) )* ) } )*$ ) 'x;
Any ideas on how to simplify the backslash processing and comment processing would be appreciated -- you can see in the 2nd comment.. I thought to use a possessive capture if two backslashes were next to each other -- followed by either NOT one of the forbidden chars, OR a backslash and 'any char' -- but that was a dismal failure and I thought that should have worked!.... (1st comment was a pitiful 1st attempt...eh!)...
And here I thought it was all cool, the example in the man page of useful code... and then I tried to use it... *smack*: reality hit.
So why'd my name conversion not work? and the 2nd comment re for handling BS and # seemed reasonable, no?? *sigh*...
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: how to go from numbered captures to named?
by davido (Cardinal) on Jul 13, 2012 at 08:01 UTC | |
by perl-diddler (Chaplain) on Jul 15, 2012 at 23:01 UTC |