tags:

views:

156

answers:

3

Need help finding or having a RegEx match a MM/YY or MM/YYYY format. My RegExFu is weak and I'm not even sure where to begin writing this.

Months should be 1-12, years, well anything beyond 2009 should be valid. Sorry for not mentioning more details before. This is used as an expiration date.

I'll add a bounty for whomever goes above and beyond and validates MM/YY or MM/YYYY format that is >= today's date. No sense letting expired stuff past the first validation layer.


I feel bad since I changed my requirements and had to be more specific in what I needed mid-question so I'll award bounties to all those who answered once the no-bounty window expires.

+1  A: 

Try this:

^(0[1-9]|1[0-2])/(19|2[0-1])\d{2}$

Constrains to actual months (1-12) and years 1900-2100.

Brad
Hhm what about 10/100 :/?
lasseespeholt
this matches "MM/YYY" aswell.
klausbyskov
@klausbyskov, I've updated it to be more precise.
Brad
@Brad, this isn't matching 11/81
jfar
Matches `1212/1999`
BrunoLM
The first half won't accept a valid, two-digit month. It's expecting 4 digits: http://rubular.com/r/5yiqpDFKyy
eldarerathis
@all, WHOOPS! Corrected.
Brad
+2  A: 

Try:

var re = new Regex(@"(?<month>\d{2})/(?<year>\d{2}|\d{4})");
var month = re.Match(yourString).Groups["month"];
...

An alternative is:

if(dateStr.Length == 5)
    myDateTime = DateTime.ParseExact("MM/YY", dateStr);
else
    myDateTime = DateTime.ParseExact("MM/YYYY", dateStr);
klausbyskov
@klausbyskov, this allows month to be 54.
Brad
Thanks for pointing out ParseExact. That makes my validation even better.
jfar
[ParseExact](http://msdn.microsoft.com/en-us/library/332de853.aspx) can take an array of formats, which is defiantly better than a regex.
Kobi
+3  A: 

What about

^(1[0-2]|0[1-9]|\d)\/(20\d{2}|19\d{2}|0(?!0)\d|[1-9]\d)$

Matches months

// 10 to 12 | 01 to 09 | 1 to 9
(1[0-2]|0[1-9]|\d)

And years

// 2000 to 2099 | 1900 to 1999
// 01 to 09 | 10 to 99
(20\d{2}|19\d{2}|0(?!0)\d|[1-9]\d)

To match anything >= 2010

/^(1[0-2]|0[1-9]|\d)\/([2-9]\d[1-9]\d|[1-9]\d)$/;

Result:

12/2009 : false
1/2010  : true
12/2011 : true
12/9011 : true
12/07   : false
12/17   : true
BrunoLM
@Bruno, that's basically my answer.
Brad
Is there a reason why you're excluding the year `00`? It's probably not good practice to use since it's kind of confusing, but it seems like it's still perfectly valid. Or does C# not allow that for date formats?
eldarerathis
@eldarerathis: The OP didn't say what ranges he is expecting. I decided to exclude `00` because it seems ambiguous to me. `00` is `1900` or `2000`? Anyway, this is just one example. What I recommend is to use `4 digits` always.
BrunoLM
Doesn't match 1/81.
jfar
@jfar: 1/81 is not of the format MM/YYYY or MM/YY. `01/81` would be, but you should edit into your question if you also want M/YYYY and M/YY.
eldarerathis
@jfar: Now it matches.
BrunoLM
You're awesome BrunoLM.
jfar
@jfar: Thanks :). I've updated with `anything beyond 2009`. I'm assuming `x >= 2010` is valid. And assuming 2 digits are `20xx`
BrunoLM