in reply to Re^2: How can I test for the representation of an integer?
in thread How can I test for the representation of an integer?

Hi sm@sh,

I'm not quite sure I understand yet, could you provide some more context? Are you trying to determine whether a regex had capture groups or not? If so, how about this?

"1" =~ /1/; print @->1?"yes\n":"no\n"; "1" =~ /(1)/; print @->1?"yes\n":"no\n"; __END__ no yes

This uses the special variable @-, aka @LAST_MATCH_START.

Update 2018-09-01: Actually, @+ will give you the number of capture groups! See my reply below for the difference.

Regards,
-- Hauke D

  • Comment on Re^3: How can I test for the representation of an integer? (updated!)
  • Download Code

Replies are listed 'Best First'.
Re^4: How can I test for the representation of an integer?
by sm@sh (Acolyte) on Apr 25, 2016 at 11:12 UTC
    Thanks - that's very interesting (@LAST_MATCH_START).
    Sorry I wasn't clear about the use case, but I'm now curious about the representation - I'm aware there are many ways to test the regexp status.
    I had been using $& to test for the general match state, but that can perform badly.

      If you want to know whether a regular expression matches, why not simply use the regular expression in boolean context? A regular expression can match a zero-width string, so testing $& won't always help. I would use something like the following:

      my $regexp = 'hello.*world'; if( /$regexp/ ) { print "Your regexp '$regexp' matches '$_'\n"; for my $match ( 0..$#- ) { print sprintf "Match %02d (%d, %d):\t[%s]\n", $match, $-[$matc +h], $+[$match], substr( $_, $-[$match], $+[$match] ); }; };

      But as you haven't told us what the overall problem is you're trying to solve, I might be wildly off the mark. Maybe read XY Problem and then restate the actual problem you're trying to solve. That might be easier to solve than removing the problem where your current approach becomes untractable.

      Hi sm@sh,

      "1"==1, "1" eq 1, and looks_like_number(1) and looks_like_number("1") are all true in Perl. The StackOverflow thread that clueless newbie linked to already contains some excellent answers - especially choroba and ikegami's answers explain the caveats of peeking under the hood. That's why I recommended looking for a different solution to your problem than figuring out difference between 1 and "1".

      Regards,
      -- Hauke D

      Are you trying to determine whether a regex had capture groups or not?
      Thanks - that's very interesting (@LAST_MATCH_START).

      Through some code I am currently working on I discovered a potential problem here, there is a subtle but very important distinction between @- and @+, from the former:

      One can use $#- to find the last matched subgroup in the last successful match. Contrast with $#+, the number of subgroups in the [last successful] regular expression.
      $ perl -MData::Dump -e '"ya"=~/(x)?/; dd $#-, \@-, $#+, \@+' (0, [0], 1, [0, undef])

      And updating my previous example:

      "1" =~ /1/ or die; print $#-?"yes\n":"no\n"; # -> no "1" =~ /(1)?/ or die; print $#-?"yes\n":"no\n"; # -> yes "1" =~ /(2)?/ or die; print $#-?"yes\n":"no\n"; # -> no !! "1" =~ /(2)?/ or die; print $#+?"yes\n":"no\n"; # -> yes