Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

date regex

by Plankton (Priest)
on Oct 13, 2003 at 18:52 UTC ( #298923=perlquestion: print w/ replies, xml ) Need Help??
Plankton has asked for the wisdom of the Perl Monks concerning the following question:

Friends,

I almost have what I think would work as a date regex. But I don't think that a regex will be able to catch bad dates like 1968-04-31, April 31st 1968.
#!/usr/local/bin/perl -w use strict; # CCYY-MM-DD[tz] my $pat = qr /^-?\d{4,}-(0\d|1[0-2])-\d\d(Z?|([+|-]{0,1}[0-2]?\d:[0-5] +\d)?)$/; while (<DATA>) { chomp; print "$_ ", /$pat/ ? "matches\n" : "does not match\n"; } __DATA__ 1968-04-02 -0045-01-01 11968-04-02 1968-04-02+05:00 1968-04-02Z invalids to follow 68-04-02 1968-4-2 1968/04/02 04-02-1968 1968-04-31
Output
bash-2.03$ ./date_regex.pl 1968-04-02 matches -0045-01-01 matches 11968-04-02 matches 1968-04-02+05:00 matches 1968-04-02Z matches invalids to follow does not match 68-04-02 does not match 1968-4-2 does not match 1968/04/02 does not match 04-02-1968 does not match 1968-04-31 matches

Plankton: 1% Evil, 99% Hot Gas.

Comment on date regex
Select or Download Code
Re: date regex Can this be done?
by hardburn (Abbot) on Oct 13, 2003 at 19:22 UTC

    Anything can be done in a regex if you use /e, ?{ }, or ??{ }. I just don't promise it will be easy :)

    If you want easy, look at Date::Manip or one of the other multitude of Date/Time modules on CPAN.

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    Note: All code is untested, unless otherwise stated

Re: date regex Can this be done?
by Ovid (Cardinal) on Oct 13, 2003 at 19:33 UTC

    Use the (??{}) construct and it's pretty easy:

    #!/usr/local/bin/perl use warnings; use strict; use Date::Simple; $|++; my $good_date = sub { my ($year,$month,$day) = ($1, $2, $3); my $date = do { no warnings 'uninitialized'; Date::Simple->new($year,$month,$day) }; return $date ? qr{(?=)} : qr{(?!)}; }; # CCYY-MM-DD[tz] my $pat = qr /^(\d\d\d\d)-(\d\d)-(\d\d)(??{$good_date->()})/; while (<DATA>) { chomp; print "$_ ", /$pat/ ? "matches\n" : "does not match\n"; } __DATA__ 1968-04-02 -0045-01-01 11968-04-02 1968-04-02+05:00 1968-04-02Z invalids to follow 68-04-02 1968-4-2 1968/04/02 04-02-1968 1968-04-31

    And the output:

    1968-04-02 matches
    -0045-01-01 does not match
    11968-04-02 does not match
    1968-04-02+05:00 matches
    1968-04-02Z matches
    invalids to follow does not match
    68-04-02 does not match
    1968-4-2 does not match
    1968/04/02 does not match
    04-02-1968 does not match
    1968-04-31 does not match

    I gave a simplified example to show you how it's done, but you'll want to flesh out that regex more.

    Cheers,
    Ovid

    New address of my CGI Course.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://298923]
Approved by davido
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (9)
As of 2015-07-05 21:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (68 votes), past polls