views:

417

answers:

4

RegularExpressionValidator.ValidationExpression="\d{10}" means only digits - 10 max.

RegularExpressionValidator.ValidationExpression="\d{10,12}" means only digits - 10, 11 or 12.

How to force strictly 10 or 12 symbols?

+6  A: 

One way is:

"\d{10}(\d{2})?"

Or you could be more explicit, at the cost of a little performance:

"^(\d{10}|\d{12})$"

The reason for the anchors in the second expression is described here:

If you experience problems with pattern-matching constructs, try wrapping the expression with "^(" and ")$". For example, "a|ab" becomes "^(a|ab)$".


Update: I was interested in why the second suggestion came up with \d{10}|\d{12} (before I fixed it) did not work correctly, and since I was curious so I decided to dip into the source code for the validator to see why this fails. I understand that the OP probably doesn't care about these details and just wanted his problem to be solved, but maybe some other people reading this thread would find the answer interesting so I'll post my findings anyway.

The RegularExpressionValidator validates both server-side and client-side using the same regular expression and in the case of \d{10}|\d{12} it fails on the client-side for length 12, but works for length 10. The source-code reveals how the match is made:

var rx = new RegExp(val.validationexpression);
var matches = rx.exec(value);
return (matches != null && value == matches[0]);

Note that this regular expression is A|B but if A matches, B is never even checked - the regular expression is not "greedy" over the pipe operation - it takes the first match it finds. So the result of matching this regular expression is that the ten digit match succeeds even if you give a 12 digit input. But then the test value == matches[0] fails because the match is not the full string.

Swapping the order of the terms, i.e. writing \d{12}|\d{10}, does work because the longer match is tested first, and the shorter match is only tested if the long match fails.

Lesson learned: it is a good idea to explicitly use anchors when using the pipe in RegularExpressionValidator to avoid having to worry about the order of the terms.

Mark Byers
@Mark Byers: Thank you very much! Very interesting. Indeed I tried the same expression as you recommended before posted a question on SO and it didn't work. And now it's absolutely clear for me why.
abatishchev
@abatischev: Glad it helped. I also learned something from investigating this.
Mark Byers
+3  A: 

Use the regular expression "pipe"

RegularExpressionValidator.ValidationExpression = "\d{10}|\d{12}"
Dillie-O
A: 
\d{10}(?:\d{2}){0,1}

should match 10 digits or 10+2 digits. the (?:.....) part is a non capturing group

Zenon
+4  A: 

^\d{10}$|^\d{12}$

The two ^$ are important if you want an exact 10 or 12 digits.

By the way, If you are making a lot of regexp this website is great : http://rubular.com/

Have fun

Niklaos
also nregex - http://www.nregex.com/nregex/default.aspx
Russ Cam
@Niklaos: Thanks! It's what I was exactly searching for. I tried the same expression as Dillie-O and Mark Byers wrote but got no success.
abatishchev
or the regulator, if you prefer and offline variant: http://sourceforge.net/projects/regulator/
Zenon