3

I'm looking to write a RegEx to validate user inputted date formats like "DD/MM/YYYY" (NOT date validation)

I'm new to RegEx, but so far i have the following:

(D{2}|M{2}|Y{2,4})[-|/]?(D{2}|M{2})[-|/]?(D{2}|M{2}|Y{2,4})

This matches the following date formats:

  • DD/MM/YYYY
  • MM/DD/YYYY
  • DD-MM-YYYY
  • MM-DD-YYYY
  • DDMMYYYY
  • MMDDYYYY
  • YYYYMMDD
  • YYYYDDMM
  • YYYY/MM/DD
  • YYYY/DD/MM
  • YYYY-MM-DD
  • YYYY-DD-MM
  • DD/MM/YY
  • MM/DD/YY
  • DD-MM-YY
  • MM-DD-YY
  • DDMMYY
  • MMDDYY
  • YYMMDD
  • YYDDMM
  • YY/MM/DD
  • YY/DD/MM
  • YY-MM-DD
  • YY-DD-MM

But unfortunately, also matches the following:

  • DDMMDD
  • YYMMYYYY
  • MMMMMM

Is there any way to only match the formats specified in the first list? The RegEx will be being used in VBA form validation.

Community
  • 1
  • 1
MrJoosh
  • 33
  • 1
  • 7

2 Answers2

2

You can use negative backreferences to ensure that you don't repeat any previous entries:

^(D{2}|M{2}|(YY){1,2})[-|\/]?(?!\1)(D{2}|M{2})[-|\/]?((?!\1|\3)(D{2}|M{2}|(YY){1,2}))$

The negative backreference (?!\1) & (?!\1|\3) prevent repetition of the entries.

Also, Y{2,4} matches 'YYY' so I changed that to (YY){1,2}.

0

Not tested for VBA but how about this:

^(((MM(?<s>[-/])?DD|DD(?<s>[-/])?MM)(?(s)[-/])?(YY|YYYY))|((YY|YYYY)(?<s>[-/])?(MM(?(s)[-/])DD|DD(?(s)[-/])MM)))$

The thought process was that there are four possible combinations ignoring separators and number of digits for a year. These are:

D M Y

M D Y

Y M D

Y D M

So this can be split into two groups - year at the start or year at the end:

^
(((MM(?<s>[-/])?DD|DD(?<s>[-/])?MM)(?(s)[-/])?(YY|YYYY))
|
((YY|YYYY)(?<s>[-/])?(MM(?(s)[-/])DD|DD(?(s)[-/])MM)))
$

I also add a named capture group to the separator just to ensure that at least two of the same character exist if present.

Dave Sexton
  • 10,768
  • 3
  • 42
  • 56