views:

57

answers:

2

I've just inherited a projected with a lot of client side validation.

In this I have found a regex checker, as expected without a comment in sight. I'll admit regex is definitely one of my failing points. (In Javascript!)

var myRegxp = /(([0]*[1-9]{1})|([1]{1}[0-2]{1}))(\/{1})((19[0-9]{2})|([2-9]{1}[0-9]{3}))$/;
if (!myRegxp.test(args.Value))
{//do fail stuff here};

I'm pretty sure from the rest of the page that it's supposed to be checking for some sort of date format. Would this pass MM/YYYY. From some early testing, it almost does it.

If this regex doesn't match MM/YYYY, what would be the best way to do this?

Any advice from the regex masters would be appreciated.

+4  A: 

It should end with MM/YYYY (where MM is 1-12 and YYYY is 1900-9999)

(matching month)

([0]*[1-9]{1})
zero or more occurences of '0', and one occurence of 1-9
Example match: 01

OR

([1]{1}[0-2]{1})
1 match of '1', 1 match of 0-2
Example match: 10

Second part (year), first it literally match '/' with:

(\/{1})

Then the year:

((19[0-9]{2})
One match of '/', 19 and two matches of 0-9 (looks like a year in the range 1900-1999)
Example match: 1900

OR

([2-9]{1}[0-9]{3})
1 match of 2-9 and thee matches of 0-9 (looks like a year in the range 2000-9999
Example match: 2000

A simplified RE:

var myRegExp = /^(0[1-9]|1[0-2])\/(19\d{2}|[2-9]\d{3})$/;

Note: \d is a character class for 0-9. I've removed parentheses used for grouping because these are not used in myRegExp.test. Replaced [0]* by 0? since it should not match 0000001/2010, but it should match 1/2010. Replaced [0]* by 0 since it should literally match 01 and not 1. The ^ and $ are anchors, causing it to match from begin to end. When leaving these out, this RE would match any text containing MM/YYYY.

Lekensteyn
In other words for @Kamal: It checks whether a certain string is MONTH/YEAR notation.
Robert Koritnik
Great explanation. Thank you. Trolling through the backend, it is indeed a MM/YYYY validation. But it's allowing values up to 19 for the month. From your explanation it is clear it shouldn't allow this?
Kamal
Whoops, I missed out some grouping. Updated my answer.
Lekensteyn
I think, correct me if I'm wrong. But should it be ([0][1-9]{1})for the first bit. So that it only allows 1-9 after a 0. And the other OR will cater for the months starting with 1 and only allow 10, 11, 12?
Kamal
If you're using `0[1-9]`, it will only match `01`, and not `1`. It depends on your preference, whether `1/2000` is valid or not. You should replace the `0?` (max. one occurrence of zero) by `0` if you want to invalidate `1/2000`.
Lekensteyn
Re: your edit. I don't want to allow 9/2010. I want to force the 0. Will my above comment solve that?
Kamal
Thank you Lekensteyn. I really have gotten my head around (this) regex now. And I appreciate the explanations as well as now I can start trying to figure it out myself.
Kamal
+1  A: 

I would agree - it is checking dates in the format MM/yyyy.

It allows any number of leading zeros on the month. It allows years matching 19xx or anything else starting with a digit between 2 and 9 inclusive. This means that it allows anything up to 9999 for the year :)

slugster
This program probably won't survive until 12/9999 :D:D:D Or there will be Y10k problem with this particular program.
Robert Koritnik
Great answers guys. I'm sure somewhere down my bloodline there'll come a day when a coder will curse his great^x grandfather for not being a forward thinker.
Kamal