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

Help, project not working, here is the code snippet:

print "$login_time\n" if $self->{'debug'}; my ($dbyear, $dbmon, $dbmday, $dbhour, $dbmin, $dbsec ) = ($login_time + =~ /^(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)$/); print "$login_time\n$dbyear, $dbmon, $dbmday, $dbhour, $dbmin, $dbsec\ +n" if $self->{'debug'};

and my output results are:

1990-01-01 00:00:00.000 1990-01-01 00:00:00.000 , , , , ,

why aren't my variables $dbxxx getting populated?

g_White

Replies are listed 'Best First'.
Re: regex not working
by trammell (Priest) on Jan 29, 2005 at 16:07 UTC
    Because your pattern
    /^(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)$/
    doesn't match your data. Particularly the milliseconds.

    Update: a pattern that matches the data you show is:

    /^(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+\.\d+)$/
    Update 2: a pattern that matches with optional fractional seconds is:
    /^(\d+)-(\d+)-(\d+) (\d+):(\d+):([0-9.]+)$/

      If I only want up to the . and it does not always appear (different databases return different format strings for that portion of the date/time) will this:

      /^(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)/

      get it done? I am a regex incompetent.

      g_White
        To me this last expression will not match if a . is indeed present.

        So if you don't know wether or not the milliseconds have a decimal part or not you could do :

        /^(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+(?:\.\d+)?)$/

        $6 will then hold the ms, with or without the optional decimal part.

        What about the rough regex:

        /^.*?(\d+)\D(\d+)\D(\d+)\D(\d+)\D(\d+)\D((\d+)\.?(\d*)+)\D?/;

        which takes care to match 6 times digits delimited in some way?

        So you'll always get the:

        ($year, $month, $mday, $hour, $minutes, $seconds) = ($1, $2, $3, $4, $5, $6);

        Yes, that will do exactly as you've stated. This is where you can try it yourself in a simple test case:

        while ( chomp($_ = <DATA>) ) { print /^((\d+)\-(\d+)\-(\d+)\s+(\d+):(\d+):(\d+))/ ? "Matched on '$_': $1\n" : "Unmatched on '$_'\n"; } __END__ 1990-01-01 00:00:00.000 1990-01-01 00:00:00.000 1991-08-06 12:21:12 1991-08-07 13:41:15.65 1992-09-2110:10:10.100
        If you want only up to '.' then use $7 instead of $6.