如何用正则验证MMDDYY格式无分隔符日期?含闰年场景
Got it, let's work through this regex problem—since you already know you can use DateTime.ParseExact but specifically want a regex solution, we need to fix the gaps in your original pattern: it didn't account for month-specific day limits (like April only having 30 days) or leap year exceptions for February 29th.
The Problem with Your Original Regex
Your original pattern ^(|(0[1-9])|(1[0-2]))((0[1-9])|(1\d)|(2\d)|(3[0-1]))((\d{2}))$ just checks that the month is 01-12 and day is 01-31, which fails for edge cases like 023020 (invalid, February has no 30th) or 022919 (invalid, 2019 isn't a leap year).
The Solution: A Regex That Handles All Cases
Here's a regex that properly validates MMDDYY by breaking down month-day rules and leap year logic for February:
^(?: (0[13578]|1[02])(0[1-9]|[12]\d|3[01])\d{2} # Months with 31 days (Jan,Mar,May,Jul,Aug,Oct,Dec) | (0[469]|11)(0[1-9]|[12]\d|30)\d{2} # Months with 30 days (Apr,Jun,Sep,Nov) | 02(0[1-9]|[12]\d|2[0-8])\d{2} # February (non-leap year: 01-28) | 0229(00|([02468][048]|[13579][26])) # February 29 (only leap years: divisible by 4) )$
How It Works
Let's break down each branch:
- 31-day months: Matches months
01,03,05,07,08,10,12followed by days01-31, then any two-digit year. - 30-day months: Matches months
04,06,09,11followed by days01-30, then any two-digit year. - Non-leap February: Matches
02followed by days01-28, then any two-digit year. - Leap February: Matches
0229only if the two-digit year is divisible by 4. The pattern(00|([02468][048]|[13579][26]))covers all two-digit years divisible by 4 (e.g.,20for 2020,00for 2000,96for 1996).
Notes
- Leap Year Edge Case: This regex assumes two-digit years like
00correspond to 2000 (a leap year). If your use case treats00as 1900 (a non-leap year), you'd need to adjust the leap year branch to exclude00—but this is rare in most modern applications. - Compressed Version: If you need a one-line regex without comments, use this:
^(?:(0[13578]|1[02])(0[1-9]|[12]\d|3[01])\d{2}|(0[469]|11)(0[1-9]|[12]\d|30)\d{2}|02(0[1-9]|[12]\d|2[0-8])\d{2}|0229(00|([02468][048]|[13579][26])))$
Test Cases
- Valid:
112517,022920,043099,123100 - Invalid:
023020,022919,130100,063121
内容的提问来源于stack exchange,提问作者sruti

