Один из способов:
"\d{10}(\d{2})?"
Или вы могли бы быть более явным, за счет небольшой производительности:
"^(\d{10}|\d{12})$"
Причина якорей во втором выражении описана здесь :
Если у вас возникли проблемы с конструкциями сопоставления с образцом, попробуйте заключить выражение в «^ (» и «) $». Например, «a | ab» становится «^ (a | ab) $».
Обновление
Меня заинтересовало, почему \d{10}|\d{12}
не работает правильно, и я решил заглянуть в исходный код для валидатора, чтобы понять, почему это не удается.
RegularExpressionValidator
проверяет как на стороне сервера, так и на стороне клиента, используя одно и то же регулярное выражение, а в случае \d{10}|\d{12}
он терпит неудачу на стороне клиента для длины 12, но работает для длины 10. Исходный код показывает, как проводится матч:
var rx = new RegExp(val.validationexpression);
var matches = rx.exec(value);
return (matches != null && value == matches[0]);
Обратите внимание, что это регулярное выражение A|B
, но если A соответствует, B никогда даже не проверяется - регулярное выражение не является "жадным" по отношению к операции конвейера - оно берет первое найденное совпадение. Таким образом, результатом сопоставления с этим регулярным выражением является совпадение из десяти цифр, даже если вы введете ввод из 12 цифр. Но тогда проверка value == matches[0]
не пройдена, потому что совпадение не является полной строкой.
Смена порядка терминов, т. Е. Запись \d{12}|\d{10}
, работает , потому что сначала проверяется более длинное совпадение, а более короткое совпадение проверяется только в случае неудачи длинного совпадения.
Извлеченный урок: хорошая идея явно использовать привязки при использовании канала в RegularExpressionValidator
, чтобы не беспокоиться о порядке терминов.