Always check if the regex was successful
If you are using regular expression to extract pieces from a string, you should always check if the regex matched before using the $1, $2, etc. variables that hold the captured substrings.
Otherwise you risk using the results of an older match.
First bad example
examples/regex_in_loop.pl
use strict; use warnings; my @cases = ( "abcde", "12345", ); for my $case (@cases) { print "$case\n"; $case =~ /([a-z])/; print "$1\n"; }
In this example we use a regex, but we don't check if it was successful or not. We just assume it was and use the content of $1. The result:
abcde a 12345 a
This was a very simplified example, and thus running it made it easy to see the problem. For both input strings, the result was the same, matched by the first string.
Show when was it matching
examples/regex_in_loop_showing_match.pl
use strict; use warnings; my @cases = ( "abcde", "12345", ); for my $case (@cases) { print "$case\n"; if ($case =~ /([a-z])/) { print("match\n"); } print "$1\n"; }
In this example I only wanted to show you that the first string matches, the second string does not. The result:
abcde match a 12345 a
Correct way to write it
examples/regex_in_loop_corrected.pl
use strict; use warnings; my @cases = ( "abcde", "12345", ); for my $case (@cases) { print "$case\n"; if ($case =~ /([a-z])/) { print("match\n"); print "$1\n"; } }
Finally we moved the use of $1 inside the condition, and used it only when there was a match.
abcde match a 12345
Final words
There are other ways to avoid the problem shown at the beginning, but this might be the most straight forward one.
Published on 2020-08-30