Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re: Re-use of a global match

by shmem (Chancellor)
on Aug 01, 2007 at 09:16 UTC ( #629999=note: print w/replies, xml ) Need Help??


in reply to Re-use of a global match

That's because of the /g switch in the first match.From perlop:
The "/g" modifier specifies global pattern matching--that is, matching as many times as possible within the string. How it behaves depends on the context. In list context, it returns a list of the substrings matched by any capturing parentheses in the regular expression. If there are no parentheses, it returns a list of all the matched strings, as if there were parentheses around the whole pattern.

In scalar context, each execution of "m//g" finds the next match, returning true if it matches, and false if there is no further match. The position after the last match can be read or set using the pos() function; see "pos" in perlfunc. A failed match normally resets the search position to the beginning of the string, but you can avoid that by adding the "/c" modifier (e.g. "m//gc"). Modifying the target string also resets the search position.

Aha. In scalar context (boolean is scalar, and you are using the match in an if-expression) the /g matching returns the next match. So the match-operator keeps its state with regard to that match, and repeating the same match returns again the next match - and there is no more match. Failing the match the match-opreator gets reset. Consider:
use strict; use warnings; my $regexp = 'Perl Monks'; if($regexp =~ m/^Perl Monks/gi) { print "\nFound.."; } else { print "\nNot Found.."; } if($regexp =~ m/^Perl Monks/gi) { print "\nFound.1."; } else { print "\nNot Found.1."; } if($regexp =~ m/^Perl Monks/gi) { print "\nFound.2."; } else { print "\nNot Found.2."; } print "\n"; __END__ Found.. Not Found.1. Found.2.

--shmem

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

Replies are listed 'Best First'.
Re^2: Re-use of a global match
by gube (Parson) on Aug 01, 2007 at 10:23 UTC

    Thanks for the above replies..

    Hi shmem

    I added modifier /c also in the match. Please check the below code. But, still the pos() for regexp is not reset. Could you please help me how to reset the position for regexp variable using modifier
    #!/usr/local/bin/perl use strict; use warnings; my $regexp = 'Perl Monks'; print "\nPos...", pos($regexp); if($regexp =~ m/^Perl Monks/gci) { print "\nFound.."; } else { print "\nNot Found.."; } print "\nPos..1.", pos($regexp); if($regexp =~ m/^Perl Monks/gi) { print "\nFound.1."; } else { print "\nNot Found.1."; }
      I added modifier /c also in the match. Please check the below code. But, still the pos() for regexp is not reset.

      which is the expected behaviour, since (perlop again):

      Options are:
      c  Do not reset search position on a failed match when /g is in effect.
      g  Match globally, i.e., find all occurrences.

      The pos() is retained in all cases until the next match is attempted, so you have to remove the /g modifier on the second match, as casiano correctly noted, which will reset pos() just before the regep engine tries to match the second time.

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://629999]
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (5)
As of 2017-09-20 00:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    During the recent solar eclipse, I:









    Results (230 votes). Check out past polls.

    Notices?