0

Currently below regex is working fine with dates but I want it to accept those date and month also which has single digit. How can I do that?

Regex should accept below formats also:

'11/4/2021' or '1/4/2021' or '1/04/2021'

dateString = '11/04/2021'

let dateformat = /^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|(([1][26]|[2468][048]|[3579][26])00))))$/g;      
              
if(dateString.match(dateformat)){      
    let operator = dateString.split('/');     
    console.log(operator)
}
BB Mevada
  • 45
  • 7
  • 2
    My general suggestion here would be to just parse the text into a proper date and validate that way. Using regex to validate dates has all sorts of issues, such as the month of February, which has 28 days, except for leap years, when it has 29 days. – Tim Biegeleisen Mar 12 '21 at 08:54
  • I would suggest you split the string first then use 3 different regex to match each part. If not at least break that monstrosity into multiple lines. You have 4 regex that you | together. This would reduce duplication. If you don't need all those capture groups use (?:...). And I agree with Tim. Use Date.parse(). – Allan Wind Mar 12 '21 at 08:54
  • Does this answer your question? [Regular Expression | Leap Years and More](https://stackoverflow.com/questions/8647893/regular-expression-leap-years-and-more) – JongHyeon Yeo Mar 12 '21 at 09:02
  • @TimBiegeleisen looks like the last regex (29\/02) handles leap years. – Allan Wind Mar 12 '21 at 09:02
  • @AllanWind It admits 29 days for February in _any_ year if I read correctly. – Tim Biegeleisen Mar 12 '21 at 09:07

3 Answers3

1

Don't. Use Date.parse() instead.

Allan Wind
  • 23,068
  • 5
  • 28
  • 38
1

For month: ^0{1}[1-9]$|^[1-9]{1}$|^1[012]{1}$

The first part is with 0, the second part is without 0, and the last one is for 10, 11 and 12.

For days: ^0{1}[1-9]{1}$|^[1-9]{1}$|^[12]{1}[0-9]{1}$|^3[01]{1}$

The first one is for days with from 1-9 starting with 0 and the second one is for the same but without the 0.

About the if the max day is 31, 30 or 28 I would use javascript for that.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
0

You are able to achieve the requested by adding to the 8th group an OR statement with the 1 to 9 characters. That's for the days. The same goes for the months.

Let me give you an example. Your matching group for the days right now is looking like this:

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

Which means that you accept all numbers which start with 0 and a digit from 1 to 9 afterwards, a number starting with either 1 or 2 and any digit afterwards, or 30.

In order to accept the digits from 1 to 9 you have to add another condition to your matching group and that is the 1 to 9 digits. So your group will look something like the following:

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

This is the most basic thing you can do. There are plenty of ways to optimize this regex and do it in a better way. You can think about the 31st day of the month, since right now it is not capturing it.

The same way I shown in the example for the days' matching group, you can do it for the months' matching group.

Stf Kolev
  • 640
  • 1
  • 8
  • 21