[tpm] Regex question

Mike Stok mike at stok.ca
Wed Jul 9 09:31:34 PDT 2008


On Jul 9, 2008, at 11:51 AM, arocker at vex.net wrote:

> Madi's original question, and one typical response:
>
>>> my $foo="ABC-987-01";
>>> my $bar=$foo;
>>> $bar=~s/(\w+-\d+)-\d+/$1/;
>>> # $bar now 'ABC-987'.
>>>
>>> That's three lines. Is there a way to do this in one line?
>>
>> Maybe I misunderstood the question...  You can say
>>
>>   my ($bar) = $foo =~ /(\w+-\d+)-\d+/;
>>
>> which will assing $1 to $bar if the match succeeds.
>>
> Compressing the assignment (which really doesn't include the original
> setting of $foo) saves one line ad one naming of $bar at the expense  
> of
> complexity and inflexibility.
>
> To comprehend the expression, you have to keep an extra level on the
> mental stack, and if you want to change the destination you risk  
> changing
> the regex. (The two expressions aren't completely equivalent; the  
> original
> doesn't change $foo, the other, like most of the suggestions, does.)
>
> Sometimes, it pays to remember the KISS principle, and the joke (?)  
> about
> a gentleman being a man who knows how to play the accordion, but  
> doesn't.

Maybe I have missed something subtle ;-)

The correct answer to Madi's question is "Yes."  (Code or the  
suggestion to remove newlines in the source were extras...)  Doing it  
in one line is possible, but whether it's a good thing is another issue.

I don't think that the suggestion above changes $foo, as all it does  
is a match in list context so $1 gets assigned to $bar if the match  
succeeds.  Have I missed an obvious "gotcha" ?

#!/usr/bin/env perl
use strict;
use warnings;

my $foo="ABC-987-01";
my ($bar) = $foo =~ /(\w+-\d+)-\d+/;

print "$foo $bar\n";

__END__

=> ABC-987-01 ABC-987

All error / success/failure checking has been left out.

Mike

-- 

Mike Stok <mike at stok.ca>
http://www.stok.ca/~mike/

The "`Stok' disclaimers" apply.






More information about the toronto-pm mailing list