A regular expression to match the actual day in a date

I need help with the appearance of a regular expression to make sure that the user enters a valid date. The string will be in the format mm/dd/yyyy

Here is what I have come up with so far.

 /\[1-9]|0[1-9]|1[0-2]\/\d{1,2}\/19|20\d\d/ 

I checked the regular expression in which the user cannot enter a day exceeding 12, and the years should start with “19” or “20”. I am having trouble figuring out some logic to check the day. The day should not exceed 31.

+10
source share
10 answers

Regex for 0-31:

 (0[1-9]|[12]\d|3[01]) 

Or, if you do not need days with a leading zero (for example, 05):

 ([1-9]|[12]\d|3[01]) 
+36
source
 use DateTime; 

Other solutions are great, maybe work, etc. Usually you want to do a little more, and then a little more, and in the end you have some crazy code and leap years, and why are you doing it yourself again?

DateTime and formatters are your solution. Use them! Sometimes they are a little overloaded, but often it works for you along the way.

 my $dayFormat = new DateTime::Format::Strptime(pattern => '%d/%m/%Y'); my $foo = $dayFormat->parse_datetime($myDateString); 

$foo now a DateTime object. Enjoy.

If your date string was not formatted correctly, $foo will be "undef" and $dayFormat->errstr will tell you why.

+13
source
  • As many noted above, if we want to check the date as a whole, then RegEx is a very bad choice.
  • But if we want to match a pattern of numbers, in this case from 01-31 , then with RegEx everything is fine, if there is some internal logic that checks the date as a whole, if necessary.
  • I see the expected answer currently not for 10, 20.

    • Test: gawk 'BEGIN{ for(i=0;i<=32;i++){ if (i ~ /^([0-2]?[1-9]|3[01])$/){print i " yes"}else {print i " no"} } }
    • This can be fixed as follows: ^([0-2]?[1-9]|3[01]|10|20)$

Therefore, please consider the following solution ...

1. Identify the sets to be matched:

  • Days with the prefix "0": {01,...,09},{10,...,31}
    • The subset {10,...,31} can be divided into => {10,...,29},{30,31}
  • Without prefix: {1,...,31} => {1,...,9},{10,...,31}

2. Corresponding regular expressions for each subset:

 --------------------------------- Sub-Set | Regular-Expression --------------------------------- {01,...,09} | [0][1-9] {10,...,29} | [1-2][0-9] {30,31} | 3[01] {1,...,9} | [1-9] --------------------------------- 

Now we can group ([0][1-9]) and ([1-9]) together as ([0]?[1-9]) . Where ? means 0 or 1 occurrence of pattern / symbol. [UPDATE] - Thanks, @MattFrear, for pointing this out.

As a result, RegEx looks like this: ^(([0]?[1-9])|([1-2][0-9])|(3[01]))$

Checked here: http://regexr.com/?383k1 [UPDATE]

+8
source
 ^(((((((0?[13578])|(1[02]))[\.\-/]?((0?[1-9])|([12]\d)|(3[01])))|(((0?[469])|(11))[\.\-/]?((0?[1-9])|([12]\d)|(30)))|((0?2)[\.\-/]?((0?[1-9])|(1\d)|(2[0-8]))))[\.\-/]?(((19)|(20))?([\d][\d]))))|((0?2)[\.\-/]?(29)[\.\-/]?(((19)|(20))?(([02468][048])|([13579][26])))))$ 

From Expressions in Category: Dates and Time

Checks the correct number of days in a month, it looks like it even processes leap years.

You can, of course, change [\.\-/] to / for permissions only.

+5
source

It's not that hard ...

 qr#^ (?: 0[1-9] | 1[012] ) / (?: 0[1-9] | 1[0-9] | 2[0-8] | (?<! 0[2469]/ | 11/ ) 31 | (?<! 02/ ) 30 | (?<! 02/ (?= ... (?: .. (?: [02468][1235679] | [13579][01345789] ) | (?: [02468][1235679] | [13579][01345789] ) 00 ) ) ) 29 ) / [0-9]{4} \z #x 
+2
source

Try:
/(0?[1-9]|1[012])\/(0?[1-9]|[12][0-9]|3[01])\/((19|20)\d\d)/

+1
source

Is regular expression required? If not, you'd better use a different approach like DateTime::Format::DateManip

 my @dates = ( '04/23/2009', '01/22/2010 6pm', 'adasdas', '1010101/12312312/1232132' ); for my $date ( @dates ) { my $date = DateTime::Format::DateManip->parse_datetime( $date ); die "Bad Date $date" unless (defined $date); print "$dt\n"; } 
+1
source

Regular expression on day 0-31:

0 [1-9] | [12] \ d | 3 [01]) without prefix 0 - when "1", "23" ...

([1-9] | [12] \ d | 3 [01]) with the prefix 0 - when "01", "04"

(0? [1-9] | [12] \ d | 3 [01]) - with or without "0" - when ""

0
source

Simplified regex:

 ([12]\d|3[01]|0?[1-9]) 

Consider the accepted answer and this expression:

 (0[1-9]|[12]\d|3[01]) 

This matches 01, but not 1

Another expression in the accepted answer:

 ([1-9]|[12]\d|3[01]) 

This matches 1 but not 01

It is not possible to add an OR clause to make them both work.

The one I suggested matches both. Hope this helps.

0
source

I have been working with this for a while, and the best of the regular expressions I have proposed is the following:

 \b(0)?(?(1)[1-9]|(3)?(?(2)[01]|[12][0-9]))\b|\b[1-9]\b 

It will correspond to the following numbers:

 1 01 10 15 20 25 30 31 

This does not match the following:

 32 40 50 90 
0
source

All Articles