First match or all matches? Perl Regular Expressions
Archive - Originally posted on "The Horse's Mouth" - 2012-11-19 23:22:46 - Graham EllisIf you match a string to a regular expression, there are often lots of ways it can match. And if you're just saying "does this match", that's fair enough ... but if you're wanting to extract the matched data, you need to give it more thought.
A Perl match to /-?\d+\.\d+/ in an if statement will give the leftmost match, and the longest match from that point - so if the data is
123454_AM_by -0.48486638 1.2125003 0.20711732
you'll match -0.48486638 (and not -0.4 and not 1.2125003 ...). You can access the matched string via $& (there are other prettier ways) if you want.
By adding a g for global on the match, and performing the match in a while loop, you can loop through all non-overlapping matches:
while ($info =~ /\s-?\d+\.\d+/g) {
print "Matched in loop to $&\n";
}
giving
Matched in loop to -0.48486638
Matched in loop to 1.2125003
Matched in loop to 0.20711732
and you could then push each matched element onto a list for later processing.
However, if you want a list of matches, there are often better ways using split (where you specify a regular expression for the separators you don't want) and the possibly grep to filter our required elements:
@m2 = grep(/^-?\d+\.\d+$/,split(/\s+/,$info));
print "Matching fields: @m2\n";
Full source code example [here], and subject covered on our Learning to program in Perl and Perl Programming course. More advanced delegates might like to take a look at our Perl for larger projects course.