Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

A regex BR variable dead in following line/command

by abdan (Acolyte)
on Nov 12, 2021 at 11:59 UTC ( #11138753=perlquestion: print w/replies, xml ) Need Help??

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

Why the regex br variable $2 vanish in :
do{ if ($whole =~ /^(.*?)^(\*{5,}..?^\*SRC)/mscg) { print "\n=======\n".$1."\n=======\n".$2;} } while($2);
How to solve to keep it alive around that

Replies are listed 'Best First'.
Re: A regex BR variable dead in following line/command
by haukex (Bishop) on Nov 12, 2021 at 14:55 UTC

    The Variables related to regular expressions are (re)set by each successful regex operation and are dynamically scoped, so if you want to use them later, you should generally always store them into other variables, and only use them if the match is successful in the first place. (A related recent thread in regards to the variables' scoping: Re: why is $1 cleared at end of an inline sub?)

    Your while($2) is outside of the dynamic scope of the regular expression, which is why it is unset there. Also, using $2 as a loop condition smells a bit fishy - I suspect it may be better if you use the if on the regex to break out of the loop via e.g. last.

      > Also, using $2 as a loop condition smells a bit fishy

      Indeed, the idiomatic expression is rather

      while( m/REGEX/g ) { ... # use groups only if match successful }

      The only reason to check $2 separately, is to make sure it's not false ( "", 0, undef, etc )

      this can be done with

      while( m/REGEX/g ) { last unless $2; ... }

      tho I doubt the OP is aware of all those false cases.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

Re: A regex BR variable dead in following line/command
by roboticus (Chancellor) on Nov 12, 2021 at 13:49 UTC

    abdan:

    If you want to keep it, then store it in a variable:

    my $x = .... do { if ($whole =~ /^(.*?)^(\*{5,}..?^\*SRC)/mscg) { print "\n=======\n".$1."\n=======\n".$2; $x = $2; } } while($x);

    The capture group variables are set every time you do a match. Can you imagine how annoying it would be if they weren't? Then you'd have to explicitly clear them before doing a match or you'd risk getting bits of old data mixed in with new data. The current automatic clearing of the group variables is a much better match to typical expected behavior.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: A regex BR variable dead in following line/command
by Corion (Patriarch) on Nov 12, 2021 at 12:13 UTC

    That really depends on your input - maybe you want to show us your input, and/or use Regexp::Debugger?

Re: A regex BR variable dead in following line/command
by hippo (Bishop) on Nov 12, 2021 at 12:25 UTC
      See Coping with Scoping.

      Although that explains local, it unfortunately doesn't explain what's going on in the OP's example (that $1 and friends are dynamically scoped).

        Indeed so. It was meant more as a suggested answer to abdan's second question rather than their first.


        🦛

Re: A regex BR variable dead in following line/command
by LanX (Sage) on Nov 12, 2021 at 12:01 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11138753]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2022-05-28 13:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Do you prefer to work remotely?



    Results (99 votes). Check out past polls.

    Notices?