Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Help understanding global flag in perl

Tags:

regex

perl

As far as I know in perl global '/g' flag means that search will replace/return all the matches throughout the string. But I am not able to understand the way it reacts to global variables while matching, can somebody explain the why there is difference between output of these two sample programs:

Version 1:

my $text = 'This is sample float value 3.2 ';

getFloat();
getFloat();

sub getFloat(){
    if ($text =~ /([0-9]+?)(.?)([0-9]+?)/is){
        print "matched> $1$2$3 ";
    }
}

Output: matched> 3.2 matched> 3.2

Version 2:(with global flag)

my $text = 'This is sample float value 3.2 ';

getFloat();
getFloat();

sub getFloat(){
    if ($text =~ /([0-9]+?)(.?)([0-9]+?)/gis){
        print "matched> $1$2$3 ";
    }
}

Output: matched> 3.2

As seen from outputs, with global flag matching occurs only once. Can someone explain this behaviour.

like image 449
scientist.rahul Avatar asked Aug 06 '11 22:08

scientist.rahul


2 Answers

With the g modifier, the string remembers the place of its last match, so you can request a match with a g in a while loop and find all the matches.

Without the g you start over each time and always find the first match.

In your case, with the g, you matched 3.2 the first time, but the second time you tried to match, there were no more matches.

Without the g you can call getFloat() a zillion times and you will always find the first match.

like image 78
Ray Toal Avatar answered Nov 08 '22 02:11

Ray Toal


When used in a list context, /g causes =~ to return all the matches. When used in a scalar context, /g causes =~ to return one match each time it is used, and then fails (returns undef) when there are no more matches, before starting again at the start of the string. (You can prevent this by using /gc.) You can also use the pos($text) function to find or set the position at which to start the match.

Without /g, =~ always returns the same match each time. This is equivalent to setting pos($text) to undef each time. (In a list context, =~ returns a list of the captures instead.)

like image 21
Neil Avatar answered Nov 08 '22 02:11

Neil