views:

65

answers:

5

I am trying to use the following regular expression to validate a date in javascript (sorry it's a bit of a brute):

"/^(((0[1-9]|[12][0-9]|3[01])\/(0[13578]|1[02])\/((19|[2-9][0-9])[0-9]{2}))|((0[1-9]|[12][0-9]|30)\/(0[13456789]|1[012])\/((19|[2-9][0-9])[0-9]{2}))|((0[1-9]|1[0-9]|2[0-8])\/02\/((19|[2-9][0-9])[0-9]{2}))|(29\/02\/((1[6-9]|[2-9][0-9])(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/"

The problem is, I'm getting an Unterminated Parenthetical Javascript error. I tried using this expression in PHP with preg_match and it works fine.

A bit stumped so any help would be much appreciated!

Edit: I should add, the date I'm trying to validate would be in a dd/mm/yyyy format.

Edit 2: Sorry, I should have clarified that I'm using the jQuery validator from position-abolute.com (http://www.position-absolute.com/articles/jquery-form-validator-because-form-validation-is-a-mess/).
The custom rule I have defined is:

"date":{
    "regex":"/^(((0[1-9]|[12][0-9]|3[01])\/(0[13578]|1[02])\/((19|[2-9][0-9])[0-9]{2}))|((0[1-9]|[12][0-9]|30)\/(0[13456789]|1[012])\/((19|[2-9][0-9])[0-9]{2}))|((0[1-9]|1[0-9]|2[0-8])\/02\/((19|[2-9][0-9])[0-9]{2}))|(29\/02\/((1[6-9]|[2-9][0-9])(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/",
    "alertText":"* Invalid date, must be in DD/MM/YYYY format."}
+1  A: 

No error in Firebug. Also regexplanet.com compiles this fine (once removing the forward slashes).

However, 21 capturing groups -- especially if they are nested -- are hardly the ideal approach in JavaScript. Parsing the matches will be a nightmare.

My suggestion would be to try break down your regexp into parts if possible.

FK82
A: 

either use /MyRegex/ or new RegExp("myRegex")

Sven Hecht
The validation plugin apparently takes a String.
FK82
well he didn't point out that he's using a validation plugin till recently. But still either // or "" both is plain wrong.
Sven Hecht
A: 

This might help:

function validDate(txtDate) {
        var regExDate = /(?:0[1-9]|[12][0-9]|3[01])\/(?:0[1-9]|1[0-2])\/(?:19|20\d{2})/;
        return regExDate.test(txtDate);
    }
Sudhir
A: 

The regex looks good parenthetical wise, but I suggest you use non-capturing groups (?: ) where you do not need to capture anything. Additionally in case you might not know you can check http://www.regular-expressions.info/ for more info.

TropicalTea
A: 

Thanks everyone for your answers. I know using such a convuluted regex isn't ideal but I'm working on an existing system and wanted to maintain consistent validation methods.

Anyway, what was happening was the regex string was being extracted by another method before being evaluated, which removed the escaping '\' characters ('\/' became '/').

The quickest solution I could think of was to replace '\/' with '[/]', as the forward slash loses it's special meaning in the character set. The regex now looks like:

/^(((0[1-9]|[12][0-9]|3[01])[/](0[13578]|1[02])[/]((19|[2-9][0-9])[0-9]{2}))|((0[1-9]|[12][0-9]|30)[/](0[13456789]|1[012])[/]((19|[2-9][0-9])[0-9]{2}))|((0[1-9]|1[0-9]|2[0-8])[/]02[/]((19|[2-9][0-9])[0-9]{2}))|(29[/]02[/]((1[6-9]|[2-9][0-9])(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/

Hope that makes sense and thanks again!

Jonathan
Double escape (`\\/`) won't do it? Other than that, from your edit I gathered that you want to validate a date of some specific format. In that case I think you might be able to simplify your regexp quite a deal.
FK82
You're right, double escape is a better solution. Not sure why I didn't think of that before the character set :S
Jonathan