an ugly perl regex trick
11:21am on Oct 26, 2012
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:
1 2 3 | 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!):
1 2 3 | 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:
1 2 3 4 5 6 7 8 9 | 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!