I am setting up this example Perl snippet to validate for months in a date:
Some scenarios I want to accept are:
MM M
#!/usr/bin/perl
use strict;
use warnings;
my $pattern;
my $month = "(0[1-9]|1[012])";
my $day = "(0[1-9]|[12]\d|3[01])";
system("cls");
do {
print "Enter in a month: ";
chomp($pattern = <STDIN>);
# We only want to print if the pattern matches
print "Pattern matches\n" if ($pattern =~ /$month/);
} while ($pattern ne "Q");
When I run this, it correctly filters from 01-12 but when I change the regex to:
$month = "(0?[1-9]|1[012])";
then the regex allows 13, 14, etc... what gives?
To validate a RegExp just run it against null (no need to know the data you want to test against upfront). If it returns explicit false ( === false ), it's broken. Otherwise it's valid though it need not match anything.
Regex to Check for Valid Username You can use [a-zA-Z][a-zA-Z0-9-_]{4,24} to force users to use a letter for the first character of their username.
A regular expression for dates (YYYY-MM-DD) should check for 4 digits at the front of the expression, followed by a hyphen, then a two-digit month between 01 and 12, followed by another hyphen, and finally a two-digit day between 01 and 31.
If you really like to use regex, you need to put ^ and $, like
"^(0?[1-9]|1[012])$"
it will not match 13, 14 ....
You shouldn't use a regular expression to do numeric range validation. The regular expression you want is:
/^(\d+)$/
Then,
if ($1 >= 1 && $1 <= 12) {
# valid month
}
This is much easier to read than any regular expression to validate a numeric range.
As an aside, Perl evaluates regular expressions by searching within the target for a matching expression. So:
/(0[1-9]|1[012])/
searches for a 0 followed by 1 to 9, or a 1 followed by 0, 1, or 2. This would match "202" for example, and many other numbers. On the other hand:
/(0?[1-9]|1[012])/
searches for an optional 0 1 to 9, or a 1 followed by 0, 1, or 2. So "13" matches here because it contains a 1, matching the first half of the regex. To make your regular expressions work as you expect,
/^(0?[1-9]|1[012])$/
The ^
and $
anchor the search to the start and end of the string, respectively.
To give you hint - month number "120" also matches in your version :-)
Change:
my $month = "(0[1-9]|1[012])";
to
my $month = /^(0[1-9]|1[012])$/;
and then play more with it
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With