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

hi monks,

quick and easy one, i hope. i want to use the matching metacharacter '{}' to match a number of instances of a character, but i want to calculate that number "on the fly" (vs hard-coding a number, or creating a variable just for that regex). i'm not sure if i can do this, but here's what i tried, which fails:

#!/usr/bin/perl use strict; use warnings; my $foo = shift || 12; my $i = 1; print "Is \`$foo' a two-digit number ... "; my $rc = ($foo =~ /^[0-9]{($i + 1)}$/) ? 'yes' : 'no'; #my $rc = ($foo =~ /^[0-9]{2}$/) ? 'yes' : 'no'; print $rc,"\n";
if i use the commented out code, it works. it is no biggie if i have to create the variable first, but it just feels like there ought to be a way to do this.

btw, i know there are betters ways to check for a two-digit number, this is just a simplified example of my problem.

thanks.

Replies are listed 'Best First'.
Re: Calculating variable {n} in regex match
by toolic (Bishop) on Jun 05, 2012 at 16:17 UTC
    It allows for a simple variable to be used, instead of an expression including a variable:
    use warnings; use strict; my $foo = shift || 12; my $i = 2; print "Is \`$foo' a two-digit number ... "; #my $rc = ($foo =~ /^[0-9]{($i + 1)}$/) ? 'yes' : 'no'; my $rc = ($foo =~ /^[0-9]{$i}$/) ? 'yes' : 'no'; #my $rc = ($foo =~ /^[0-9]{2}$/) ? 'yes' : 'no'; print $rc,"\n"; __END__ Is `12' a two-digit number ... yes

    Add re to your code to see what is happening under the hood:

    use re 'debug';
      toolic,

      i know i can merely do $i = 2, but i am wondering if it is possibly to instead not have to set/reset any variable, but instead calculate it using the ($n + 1) convention.

      thanks for the use re 'debug' tip, never used that before.
Re: Calculating variable {n} in regex match
by temporal (Pilgrim) on Jun 05, 2012 at 17:08 UTC

    It sounds like the OP wants to capture the number of occurrences entirely within the regex, something like:

    $foo =~ m/[0-9]({\d+})/ print "$foo has $1 digit(s)";

    ... if that were possible (it isn't). This would allow the counting match to be thrown in with a longer regex that is matching on other properties as well. This is probably possible through clever use of code evaluation (?{code}) and interpolation within the regex.

    However, if all you need to do is count in the regex then you could use the 'goatse' operator:

    my $length =()= $foo =~ /[0-9]/g; print "$foo has $length digit(s)";

    Seems better than looping and incrementing, anyway.

    Strange things are afoot at the Circle-K.

      FWIW:

      >perl -wMstrict -le "my $s = '123 234 3456789 3210 34567'; ;; my @m = $s =~ m{ \b ((\d) (??{ qr{\d{$^N}} })) \b }xmsg; print qq{@m}; ;; my $i = 2; @m = $s =~ m{ \b (??{ ++$i; qr{\d{$i}}; }) \b }xmsg; print qq{@m}; " 234 2 3210 3 123 3456789
        okay, AnomalousMonk, this works:
        # the original number of integers to test (will be one-upped) my $i = 1; # the input string to be tested (a number) my $foo = shift; # see if the input string is a two-digit number my $rc = ($foo =~ m{ \b (??{ ++$i; qr{\d{$i}}; }) \b }xmsg) ?'Y' :'N';
        very clever...thanks.
      ... if that were possible (it isn't). This would allow the counting match to be thrown in with a longer regex that is matching on other properties as well. This is probably possible through clever use of code evaluation (?{code}) and interpolation within the regex.

      that's actually kind of hoping for...a clever use of eval - but i couldn't figure that out. anyway, sounds like what i want is not possible, at least in a straight-forward fashion.

Re: Calculating variable {n} in regex match
by cheekuperl (Monk) on Jun 05, 2012 at 16:25 UTC
    $num='36737'; $idx=0; while($num=~m/[0-9]{$idx}/) { $idx++; } $idx--; # adjusment to get correct answer print "\n$num has $idx digits ";

    Is this what you wanted?

Re: Calculating variable {n} in regex match
by GrandFather (Saint) on Jun 07, 2012 at 21:34 UTC

    What's the bigger problem you are trying to solve? Kinda sounds like using a claw hammer to remove a tyre when you should be using a tyre iron.

    True laziness is hard work
Re: Calculating variable {n} in regex match
by aaron_baugher (Curate) on Jun 15, 2012 at 05:06 UTC

    I learned this here at PerlMonks: you can execute an expression inside a string or a regex pattern by wrapping it in @{[]}, like so:

    #!/usr/bin/env perl use Modern::Perl; my $str = 'abc123efghijk'; my $i = 2; if( $str =~ /(\d{@{[$i+1]}})/ ){ say $1; } # output -> 123

    Aaron B.
    Available for small or large Perl jobs; see my home node.

      nice, aaron.

      my $rc = ($foo =~ /^(\d{@{[$i+1]}})$/

      always w/Perl, TIMTOWTDI...