Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Match regex and assign results in single line of code

Tags:

regex

perl

my($variable) = "some string" =~ /(e\s*str)/;

This works because

If the /g option is not used, m// in list context returns a list consisting of the subexpressions matched by the parentheses in the pattern, i.e., ($1, $2, $3 …).

and because my($variable) = ... (note the parentheses around the scalar) supplies list context to the match.

If the pattern fails to match, $variable gets the undefined value.


Why do you want it to be shorter? Does is really matter?

$variable = $1 if $variable =~ /(find something).*/;

If you are worried about the variable name or doing this repeatedly, wrap the thing in a subroutine and forget about it:

 some_sub( $variable, qr/pattern/ );
 sub some_sub { $_[0] = $1 if eval { $_[0] =~ m/$_[1]/ }; $1 };

However you implement it, the point of the subroutine is to make it reuseable so you give a particular set of lines a short name that stands in their place.


Several other answers mention a destructive substitution:

( my $new = $variable ) =~ s/pattern/replacement/;

I tend to keep the original data around, and Perl v5.14 has an /r flag that leaves the original alone and returns a new string with the replacement (instead of the count of replacements):

my $match = $variable =~ s/pattern/replacement/r;

You can do substitution as:

$a = 'stackoverflow';
$a =~ s/(\w+)overflow/$1/;

$a is now "stack"


Well, you could say

my $variable;
($variable) = ($variable = "find something soon") =~ /(find something).*/;

or

(my $variable = "find something soon") =~ s/^.*?(find something).*/$1/;

From Perl Cookbook 2nd ed 6.1 Copying and Substituting Simultaneously

$dst = $src;
$dst =~ s/this/that/;

becomes

($dst = $src) =~ s/this/that/;

I just assumed everyone did it this way, amazed that no one gave this answer.


Almost ....

You can combine the match and retrieve the matched value with a substitution.

$variable =~ s/.*(find something).*/$1/;

AFAIK, You will always have to copy the value though, unless you do not care to clobber the original.