an ugly perl regex trick
October 26, 2012 @ 11:21
I haven’t been doing a lot of perl lately, but a lot of my stuff at work is still perl, so every now and then I have to do some maintenance or add new features. Today I was working on new features.
One issue with perl is that there’s no way to get an array of regular expression matches without building it yourself in a really ugly way. I had a situation where I was getting a ‘1’ returned in array of match captures when doing this:
if (my @matches = ($url =~ $test)) {
...
}
If there are captures in $test, you get the list of them, but if not, you’ll get a ‘1’ in there, in some cases. Frustrating.
You can do this (Thanks Paul!):
if (my @matches = ($url =~ $test)) {
@matches = () if @+ < 2;
}
This works great… but in working out what I needed, I decided I wanted to handle both normal captures and named captures. So here’s what I got:
if ($uri =~ $test) {
# store named matches
%matches = map {$_ => $+{$_}} keys(%+);
# store not-named matches by number
for (my $i=1; $i<= $#-; $i++) {
$matches{$i} = substr($uri, $-[$i], $+[$i] - $-[$i]);
}
}
And that is some ugly perl. It works though!