grobber has asked for the wisdom of the Perl Monks concerning the following question:

I would like to evaluate a piece of code returning a positive integer and interpolate that in a '{}' quantifier in a regex, as in
$string =~ /x{<code goes here>}/
I have tried to do the code-evaluation bit via the (??..) construct, but something like, say
$string =~ /(a+)x{(??{length $1})}/
returns the dreaded Unescaped left brace in regex is deprecated here warning. I realize that this precise regex can be reworked into
$string =~ /(a+)(??{$1 =~ s/a/x/gr})/
to achieve the intended goal, but the point of the question is whether, nevertheless, there is some procedure that will allow code interpolation between non-literal regex braces.

Replies are listed 'Best First'.
Re: interpolating code in regex brace quantifier
by ikegami (Patriarch) on Mar 08, 2019 at 21:42 UTC

    Sure, you can interpolate there.

    my $num_zeds = "13"; /z{$num_zeds}/

    But you don't want interpolation. You want something like the following:

    /(a+)(??{ 'x{'.length($1).'}' })/
      This does it, thank you! And yes, I misspoke: it wasn't quite "interpolation" I was after..
        Note that you can also achieve the desired result through recursion
        (a(?1)?x)
Re: interpolating code in regex brace quantifier
by AnomalousMonk (Archbishop) on Mar 08, 2019 at 22:31 UTC

    If you have Perl version 5.10+ (update: and I see now that you use the  /r modifier on the  s/// in one of your OPed code examples, so you must have at least 5.14), the Extended Patterns  (?(condition)yes-pattern) construct where condition is  (?{ CODE }) may be of interest as it doesn't have so much scary "experimental feature" stink on it.

    c:\@Work\Perl\monks>perl -wMstrict -le "use 5.010; ;; for my $s (qw(aaxyxyxy aaaxyxyxy aaaaxyxyxy)) { my $match = $s =~ m{ \b (a+) ((?: xy)+) \b (?(?{ 2 * length($1) != length($2) }) (*FAIL)) }xms; print $match ? ' ' : 'NO ', qq{match '$s'}; } " NO match 'aaxyxyxy' match 'aaaxyxyxy' NO match 'aaaaxyxyxy'
    To a very limited degree, you can get away from absolute-capture numbering with tricks like this:
    c:\@Work\Perl\monks>perl -wMstrict -le "use 5.010; ;; for my $s (qw(aaxyxyxy aaaxyxyxy aaaaxyxyxy)) { my $match = $s =~ m{ \b (a+) (?{ length $^N }) ((?: xy)+) \b (?(?{ 2 * $^R != length $^N }) (*FAIL)) }xms; print $match ? ' ' : 'NO ', qq{match '$s'}; } " NO match 'aaxyxyxy' match 'aaaxyxyxy' NO match 'aaaaxyxyxy'
    And then there are named captures. See also Special Backtracking Control Verbs for (*FAIL).


    Give a man a fish:  <%-{-{-{-<

Re: interpolating code in regex brace quantifier
by tybalt89 (Monsignor) on Mar 08, 2019 at 22:10 UTC