Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

Regular expression for date

by perlee (Initiate)
on Aug 25, 2008 at 07:47 UTC ( #706645=perlquestion: print w/replies, xml ) Need Help??

perlee has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,

I just got tired of trying to know my code isnt working. Need ur help.

This is what I have : to match the date in 10-01-08 format.
do { print "Enter Date. For Ex: 10-01-08 \n"; chomp($date = <STDIN>); } while ($date =~ /0[1-9]|1[0-2]-0[1-9]|1[0-9]|2[0-9]|3[0-1]-0[8-9]|1[ +0-9]/);
However the loop never enters again in case of a wrong input.

I have also tried (for simplicity)

#while ($date !~ /(\d\d)[-](\d\d)[-](\d\d)/);
On 10-01-08..Loop is not entered again (fine)
On 100-01-08..Loop is not entered again (why)
on xx-xx-xx..Loop is not entered again (fine)

What is that I am missing..


Replies are listed 'Best First'.
Re: Regular expression for date
by moritz (Cardinal) on Aug 25, 2008 at 07:59 UTC
    However the loop never enters again in case of a wrong input.

    Well, a while loop stops when the condition isn't true anymore. That's a feature ;-)

    If you don't want that behaviour, don't use a while loop with the regex match in the condition, rather something like this:

    while (<>) { chomp; if (m/your regex here/) { # work with it } else { print "Input '$_' not recognized as a date\n"; } }

    Update: I think you shouldn't try to match only numbers in the allowed range, because it makes the regex overly complicated, and you won't catch all errors in the regex anyway (think of February 30th), so you have to validate your input after the regex in any case.

    Something as simple as m/^\d\d-\d\d-\d\d$/ might do for you.

Re: Regular expression for date
by Skeeve (Parson) on Aug 25, 2008 at 07:56 UTC

    Because of your missing code tags, I can't really tell, but it seems your loop runs WHILE the re matches and not UNTIL it matches.

    and you don't anchor (/^$/) your RE so "this 123401-01-0123456 is not a date" as input will also match.

Re: Regular expression for date
by fmerges (Chaplain) on Aug 25, 2008 at 09:45 UTC


    I would recommend you to take a look at modules like Date::Manip.


    fmerges at
Re: Regular expression for date
by Grey Fox (Chaplain) on Aug 25, 2008 at 13:02 UTC
    I have found very helpful working with regex's. Lots of good examples. Such as
    (19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])
    for matching dates ie. yyyy-mm-dd.
    -- Grey Fox
    "We are grey. We stand between the darkness and the light" B5
Re: Regular expression for date
by didess (Sexton) on Aug 25, 2008 at 20:47 UTC
    Hi !
    1st : Tell us what you want from this script: I suppose it's : make someone enter a date until what he/she types is a "good" date (in "good" format). right ? If yes, you loop until the entry is OK ? 2nd : the format you show is not clear : It could be : 2008, January the 1st 2001, January the 8th, ... and so on It should be better to write it MM-DD-YY (for month, day, year). (FYI + :I'm french and we display dates as DD/MM/YY) for this format, the regex "could" be: (0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])-\d\d but : it ignores that the maximum number of days depends on the month( +28,29,30,31), it ignores leap years (February 28th or 29 th ?) You should use the function "timelocal()" from the standard module "Time::Local" : try to transform the date you have to validate into a +n "epoch" time (as the function time() returns) : if the function fai +ls, the date is wrong : this script seems to work: use Time::Local timelocal; my ($m,$d,$y); do { my $date; print "date (MM-DD-YY) ? "; $date=<>; chomp($date); ($m,$d,$y)=split(/-/,$date); $m -= 1; $y += 1900; } until(timelocal(0,0,0,$d,$m,$y));
    I hope it adresses your need and will help you
      Apologizes : The previous script hanged on bad date, this one runs better (thanks to "eval") !
      use Time::Local timelocal; my ($m,$d,$y,$t); do { my ($date); print "date (MM-DD-YY) ? "; $date=<>; chomp($date); ($m,$d,$y)=split(/-/,$date); $m -= 1; $y += 1900; $t = eval "timelocal(0,0,0,$d,$m,$y)"; } until (!$t);

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://706645]
Approved by moritz
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (3)
As of 2022-10-02 13:07 GMT
Find Nodes?
    Voting Booth?
    My preferred way to holiday/vacation is:

    Results (9 votes). Check out past polls.