in reply to How to know that a regexp matched, and get its capture groups?

if ( $line =~ $re ) { $cb->(@{^CAPTURE}); last;
  • Comment on Re: How to know that a regexp matched, and get its capture groups?
  • Download Code

Replies are listed 'Best First'.
Re^2: How to know that a regexp matched, and get its capture groups?
by choroba (Cardinal) on Jan 10, 2023 at 11:49 UTC
    Note that you need 5.26+ for @{^CAPTURE}.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
      update

      I don't recommend the following code anymore

      rather

      if ( my (@caps) = ($line =~ $re) ) { no warnings 'uninitialized'; @caps = () if $caps[0] ne $1; # reset pseudo capture +s $cb->(@caps); last; }
      /update

      This should be backward compatible

      my (@matches) = ($line =~ $re) if (defined $&) { $cb->(@matches); last; }

      # tests...

      use v5.12; use warnings; for my $str ("AB","") { say "****** str=<$str>"; for my $re ( qr/../, qr/(.)(.)/, q/XY/, q/(X)Y/, q// ) { say "--- re=<$re>"; my @captures = $str =~ $re; if ( defined $& ) { say "matched" } else { say "no match" } if (defined $1) { say "with captures <@captures>"; } else { say "no captures"; } } }

      ****** str=<AB> --- re=<(?^u:..)> matched no captures --- re=<(?^u:(.)(.))> matched with captures <A B> --- re=<XY> no match no captures --- re=<(X)Y> no match no captures --- re=<> matched no captures ****** str=<> --- re=<(?^u:..)> no match no captures --- re=<(?^u:(.)(.))> no match no captures --- re=<XY> no match no captures --- re=<(X)Y> no match no captures --- re=<> matched no captures

      Cheers Rolf
      (addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
      Wikisyntax for the Monastery

        But...

        > See "Performance issues" above for the serious performance implications of using this variable (even once) in your code.

        perlvar

        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
        >
        my (@matches) = ($line =~ $re) if (defined $&) { $cb->(@matches); last; }

        nope, the real problem is that @matches = (1) if it matched without capture groups in $re

        new attempt:

        if ( my (@caps) = ($line =~ $re) ) { @caps = () if $caps[0] ne $1; # reset pseudo capture +s $cb->(@caps); last; }

        Full backwards compatible and no performance penalty.

        OK?

        Cheers Rolf
        (addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
        Wikisyntax for the Monastery