Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use a regular expression to validate month input?

Tags:

regex

perl

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?

like image 348
coson Avatar asked Jan 26 '10 07:01

coson


People also ask

How do you validate expressions in regex?

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.

How do you pass an input field in regex?

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.

Which of the following regular expression passes the calendar date?

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.


3 Answers

If you really like to use regex, you need to put ^ and $, like

"^(0?[1-9]|1[012])$"

it will not match 13, 14 ....

like image 146
YOU Avatar answered Oct 16 '22 13:10

YOU


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.

like image 22
Greg Hewgill Avatar answered Oct 16 '22 13:10

Greg Hewgill


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

like image 5
MBO Avatar answered Oct 16 '22 12:10

MBO