tags:

views:

99

answers:

6

Hi, I want to be able to do a regex match on a variable and assign the results to the variable itself. What is the best way to do it?

I want to essentially combine lines 2 and 3 in a single line of code:

$variable = "some string";
$variable =~ /(find something).*/;
$variable = $1;

Is there a shorter/simpler way to do this? Am I missing something?

+3  A: 

You can do substitution as:

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

$a is now stack

codaddict
There is a problem with this, It will only replace the original variable if the entire string is present in the search pattern. If I were to use, say, /(\w+)over/ for matching, this wouldn't work.
prateekmi2
In that case you'll have to use anchors as `$a =~ s/^(\w+)over.*/$1/;` `$a` is now `stack`
codaddict
The pattern is arbitrary, matches do not necessarily begin or end at a line or word boundary. In any case, thanks, I guess there isn't any obviously simple way to do it. My primary concern was that I have to do this often, and it looks repetitive.
prateekmi2
+1  A: 

Almost ....

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

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

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

Peter Tillemans
+3  A: 

Well, you could say

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

or

(my $variable = "find something soon") =~ s/^.*?(find something).*/$1/;
Chas. Owens
I'd rather use the variable definition separately for clarity's sake, but yes this is a good solution for quick searches. Thanks.
prateekmi2
+1  A: 

I do this:

#!/usr/bin/perl

        $target = "n: 123";
            my ($target) = $target =~ /n:\s*(\d+)/g;
                print $target; # the var $target now is "123"
Jet
+2  A: 
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.

Greg Bacon
+2  A: 

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.

brian d foy