2

I wanted to validate two date fields with the format "dd / mm / yyyy". But the validation of the second date always gives false.

var pattern = /\d{2}\/\d{2}\/\d{4}/gi;

if (pattern.test(date1) && pattern.test(date2)) {
       //Do something
   } 

I tried in the console of Chrome and These are the results. Why is it not validated correctly?

var pattern= /\d{2}\/\d{2}\/\d{4}/gi
pattern.test("21/12/2008");
true
pattern.test("21/12/2009");
false
pattern.test("21/12/2008");
true
pattern.test("21/12/2009");
false
Chen Hanhan
  • 1,549
  • 6
  • 15
  • 20

1 Answers1

3

If you want your string to be only a date:

var pattern = /^\d{2}\/\d{2}\/\d{4}$/;

If you want your string to contain a date:

var pattern = /\d{2}\/\d{2}\/\d{4}/;


What wasn't working:

i is case insensitive, meaningless when searching for dates with numbers and /s

g means global, which has interesting implications on our regular expression...

Try running this example in the console:

var pattern = /\d{2}\/\d{2}\/\d{4}/gi;
pattern.test("21/12/2009");
true
pattern.test("21/12/2008");
false
pattern.test("21/12/2008");
true
pattern.test("21/12/2009");
false
pattern.test("21/12/2009");
true
pattern.test("21/12/2009");
false

Note that there is no bearing on what we send to the test, it just flip-flops true-false.

This is because javascripts regular expression engine is impure when using the g flag. It keeps state from test to test. From this question: Interesting test of Javascript RegExp

When you use a global flag on a JS RegExp the "test" and "exec" methods each halt at the first match but keep a pointer to where they stopped searching in the string. That pointer can be inspected on the lastIndex property. When you call "test" or "exec" again it begins searching for a match starting at the lastIndex.

So, when you test a RegExp on a string that matches the entire string the lastIndex is set to the end of the string. The next time you test it starts at the end of the string, returns false, and sets lastIndex back to zero.

We can see this behavior continuing from our code example above:

pattern.test("21/12/2009");
true
pattern.lastIndex
10
pattern.test("21/12/2009");
false
pattern.lastIndex
0
pattern.test("21/12/2009");
true
Community
  • 1
  • 1
Kallmanation
  • 1,132
  • 7
  • 11