CJ7
CJ7

Reputation: 23275

Assign regex capture in one statement

I have found this is a way to assign a regex capture in one statement:

$str1 = "Hello World";
($str2) = $str1 =~ m[(.+?)World];
print $str2 . "\n";  # output is "Hello "

Why are the brackets around $str2 necessary?

Upvotes: 0

Views: 47

Answers (2)

ikegami
ikegami

Reputation: 385565

Try the following:

use feature qw( say );

my @a = qw( a b c );

my $x   = @a;
my ($y) = @a;

say $x;  # This outputs 3
say $y;  # This outputs a

Making the LHS of the assignment operator look "listy" affects the context in which the RHS of the assignment operator is evaluated.

So the parens affect the context in which the regex match operator is evaluated.

  • When a regex match operator is evaluated in scalar context, it returns whether a match was found or not. This allows you to do if (/pat/).
  • When a regex match operator is evaluated in list context, it returns the strings it captured. This allows you to do my @matches = /pat/.

Upvotes: 1

Cfreak
Cfreak

Reputation: 19309

Perl is weird in that functions (which internally a regex is) can be written to understand the context of what needs to be returned.

When you use:

$str2 = $str1 =~ m[(.+?)World];

The regex function can see you want a scalar value returned and so assigns the value of 1 if matched or 0 if not matched (perl has no constants for true and false). But when you add parenthesis, the function knows you want an array, you're just immediately assigning the array's single element back to a scalar value.

It would also work if you did

@str2 = $str1 =~ m[(.+?)World];

In that case you could get your value with $str2[0]

If you wanted to return based on context in your own functions you can use the wantarray keyword.

Upvotes: 1

Related Questions