-1

I am trying to validate a date using regexp (it's for homework on regexp - yes I know there are better ways doing this in Java using the API)

So far I managed the following expression:

(0[1-9]|[12][0-9]|3[01])/(0[1-9]|1[012])/((18|19|20|21)\\d\\d)

I would like to add a check for February, i.e. cannot have 30 and 31 in the days is 2 is in the month (let's assume no leap year check)

How can I add this check into my expression?

Joly
  • 3,218
  • 14
  • 44
  • 70

2 Answers2

2

For the format dd/mm/yyyy

^(?:(?:[12][0-9]|0?[1-9])/0?2|(?:30|[12][0-9]|0?[1-9])/(?:0?[469]|11)|(?:3[01]|[12][0-9]|0?[1-9])/(?:0?[13578]|1[02]))/[0-9]{4}$

The only problem with this regex is, that it will match the 29th of february of every year.


This regular expression consists of:

(?:[12][0-9]|0?[1-9])/0?2

This part trys to match the correct day and month if the month is february. (From 1st to 29th of february)


If the month is not february try to match:

(?:30|[12][0-9]|0?[1-9])/(?:0?[469]|11)

This part trys to match every month that has 30 days. (it's the month 4,6,9 and 11) (From 1st to 30th day of month).


If the month also is not April, June, September, or November

(?:3[01]|[12][0-9]|0?[1-9])/(?:0?[13578]|1[02])

This part trys to match the month (1, 3, 5, 7, 8, 10 and 12)


The last part: [0-9]{4} matches the year. (Every 4-digit number)


If you want the regex to match only till 28th of february use:

^(?:(?:1[0-9]|2[0-8]|0?[1-9])/0?2|(?:30|[12][0-9]|0?[1-9])/(?:0?[469]|11)|(?:3[01]|[12][0-9]|0?[1-9])/(?:0?[13578]|1[02]))/[0-9]{4}$

If you want the regex to match only till 28th of february dd/mm/yyyy with required leading zero if lower than 2 digits: (you just have to replace all 0? with 0)

^(?:(?:1[0-9]|2[0-8]|0[1-9])/02|(?:30|[12][0-9]|0[1-9])/(?:0[469]|11)|(?:3[01]|[12][0-9]|0[1-9])/(?:0[13578]|1[02]))/[0-9]{4}$
Andie2302
  • 4,825
  • 4
  • 24
  • 43
  • I would use `[1-9][0-9]*` for the year - can't see any reason why we should restrict it beyond that – Deltharis Sep 12 '14 at 22:08
  • This is better! Please can you walk me through the explanation? – Joly Sep 12 '14 at 22:11
  • How can I change this to accept only 28 days in Feb please and let's assume no check for leap year? – Joly Sep 12 '14 at 22:48
  • Thanks! new problem: it doesn't follow the format I expect: dd/mm/yyyy, it accepts 1/9/2014 for example – Joly Sep 12 '14 at 23:26
0

Nasty regex.

    String days30 = "(0{0,1}[1-9]|[12][0-9]|30)";
    String days31 = "(0{0,1}[1-9]|[12][0-9]|3[01])";
    String days28 = "(0{0,1}[1-9]|1[0-9]|2[0-8])";
    String month30 = "(0{0,1}(4|6|9)|11)";
    String month31 = "(0{0,1}(1|3|5|7|8)|1(0|2))";
    String years = "(17|18|19|20)\\d\\d";
    String dateExpr = "((" + days30 + "/" + month30 + ")|(" + days31 + "/" + month31 + ")|(" + days28 + "/02))/" + years;

Updated

Do not use regular expressions to validate dates! That question was a typical nonsense homework but I accepted the challenge.

Note also, that this regular expression is not the best you could come up with, but it is clear and simple.

Considering the compile and parse time, it is however much faster than the look ahead ones.

Hannes
  • 2,018
  • 25
  • 32