user15964
user15964

Reputation: 2639

value of binding operator expression in perl

I have some doubt about the outcome of a binding operator expression in perl. I mean expression like

string =~ /pattern/

I have done some simple test

$ss="a1b2c3";
say $ss=~/a/;   # 1
say $ss=~/[a-z]/g;  # abc
@aa=$ss=~/[a-z]/g;say @aa;  # abc
$aa=@aa;say $aa;    # 3
$aa=$ss=~/[a-z]/g;say $aa;  # 1

note the comment part above is the running result.

So here comes the question, what on earth is returned by $ss=~/[a-z]/g, it seems that it returned an array according to code line 3,4,5. But what about the last line, why it gives 1 instead of 3 which is the length of array?

Upvotes: 1

Views: 255

Answers (1)

zdim
zdim

Reputation: 66883

The return of the match operator depends on the context: in list context it returns all captured matches, in scalar context the true/false. The say imposes list context, but in the first example nothing is captured in the regex so you only get "success."

Next, the behavior of /g modifier also differs across contexts. In list context, with it the string keeps being scanned with the given pattern until all matches are found, and a list with them is returned. These are your second and third examples.

But in scalar context its behavior is a bit specific: with it the search will continue from the position of the last match, the next time round. One typical use is in the loop condition

while (/(\w+)/g) { ... }

This is a bit of a tokenizer: after the body of the loop runs the next word is found, etc.

Then the last example doesn't really make sense; you are getting the "normal" scalar-context matching success/fail, and /g doesn't do anything -- until you match on $ss the next time

perl -wE'
    $s=shift||q(abc); 
    for (1..2) { $m = $s=~/(.)/g; say "$m: $1"; }
'

prints lines 1:a and then 1:b.

Outside of iterative structures (like while condition) the /g in scalar context is usually an error, pointless at best or a quiet bug.

See "Global matching" under "Using regular expressions" in perlretut for /g. See regex operators in perlop in general, and about /g as well. A useful tool to explore /g workings is pos.

Upvotes: 3

Related Questions