Alan Wayne
Alan Wayne

Reputation: 5394

Regex for date pattern?

Trying to write a regex expression in C# that accepts any/all of the following:

  1. 02/01/1968
  2. 2/01/1968
  3. 2/1/1968

(This question is somewhat different then other similar questions in that this is to be a single word, in mm/dd/yyyy format. Only the pattern is needed without verification as to its possibility. i.e., 99/99/9999 is o.k.)

I am getting nowhere fast. Here is as far as I've gotten (which only recognizes 02/01/1968):

Regex regex = new Regex(@"^\d{2}/\d{2}/\d{4}$",RegexOptions.IgnorePatternWhitespace);
Match x = regex.Match(birthdate);
if (x.Success == false) return;

Thanks for any help. (An explanation with the regex would be most appreciated).

Upvotes: 3

Views: 25045

Answers (4)

Kenneth_pro_
Kenneth_pro_

Reputation: 30

This will work:

public static class Date_Regex
{
    static string DateRegex = @"\d?[\/|\-|\s]?\d?[\/|\-|\s]\d(\s?)[\/|\-|\s]?\d?(\s?)[\/|\-|\s]\d{4}[\s]?$"; 
    public static string RegexMatches(string content)
    {
        StringBuilder sb = new StringBuilder();
        foreach (Match match in Regex.Matches(content, DateRegex, RegexOptions.Multiline)) 
        {
            sb.Append(match.Value + "; ");
        }
        return sb.ToString();
    }

}

Upvotes: 0

Pluto
Pluto

Reputation: 3026

Here's a regex that checks the right number of days per month, including for February during leap years:

var reg = new Regex(@"\b(((0?[469]|11)/(0?[1-9]|[12]\d|30)|(0?[13578]|1[02])/(0?[1-9]|[12]\d|3[01])|0?2/(0?[1-9]|1\d|2[0-8]))/([1-9]\d{3}|\d{2})|0?2/29/([1-9]\d)?([02468][048]|[13579][26]))\b", RegexOptions.ECMAScript | RegexOptions.ExplicitCapture);

Breaking up the regex this way should be easy to understand:

  • Months with 30 days: 0?[469]|11

  • Days maxed at 30: 0?[1-9]|[12]\d|30

  • Months with 31 days: 0?[13578]|1[02]

  • Days maxed at 31: 0?[1-9]|[12]\d|3[01]

  • Days maxed at 28: 0?[1-9]|1\d|2[0-8]

  • Any year from 1000+ (including 2 digit years): [1-9]\d{3}|\d{2}

  • Feb 29: 0?2/29

  • Last two digits of leap years (divisible by 4): [02468][048]|[13579][26]

  • RegexOptions.ECMAScript is important to specify to ensure \d only matches 0-9 digits from English.

  • RegexOptions.ExplicitCapture eliminates the need for non-capturing groups of (?:)

Upvotes: 5

hwnd
hwnd

Reputation: 70750

If you must use regex to validate the format, define the {min,max} in the range quantifier:

^\d{1,2}/\d{1,2}/\d{4}$

Upvotes: 4

Eser
Eser

Reputation: 12546

As mentioned in comments, use a datetime parser. To get the right regex(returning only valid datetimes) can be very complex and hard to maintain.

var formats = new[] { "d/M/yyyy", "dd/M/yyyy", "d/MM/yyyy", "dd/MM/yyyy" };
DateTime dt;
if (DateTime.TryParseExact(input, formats, null, DateTimeStyles.None, out dt))
{
    //parsed correctly
}

BTW: It is not clear in your question whether you want dd/mm or mm/dd, I chose the first one

Upvotes: 15

Related Questions