views:

31

answers:

1

I'm using php's preg_match to get a named subgroups from a string. I'm parsing user-generated date/time strings into well-formatted date/time tokens.

Here's my regex

~(?P<month>\d?\d)(/|-)(?P<day>\d?\d)(/|-)(?P<year>\d\d\d?\d?) +(?P<time>[\d: +((A|a)|(P|p))(M|m)]+)~i

And it correctly parses dates like

01-17-10 09:30 pm
2/1/2010 06:19am

into their constituent parts. However, it accepts 02/11/2010 06:19, with no am/pm string, which I'd like it not to do. What am I doing wrong?

+3  A: 

You’re using the character class [\d: +((A|a)|(P|p))(M|m)] for your time expression. This character set describes just one character and not a sequence with a defined pattern.

Try (?P<time>\d\d?:\d\d *[ap]m) instead:

~(?P<month>\d\d?)(/|-)(?P<day>\d\d?)(/|-)(?P<year>\d\d\d?\d?) +(?P<time>\d\d?:\d\d *[ap]m)~i
Gumbo
Awesome! Thanks.