2014-03-30 64 views
2

我需要验证账户的账户号码。 有效号可以是一个恰好数字或3个基团的用连字符隔开数字(2位- 3位数- 6位)序列正则表达式 - 验证具有两种不同的模式

我尝试这样做:

/^([0-9]{11})|([0-9]{2}-[0-9]{3}-[0-9]{6})$/ 

但它只适用于第二条规则。第一条规则不起作用,因为它允许超过11位

这是我如何使用正则表达式在我的js函数的数字:

var re = /^([0-9]{11})|([0-9]{2}-[0-9]{3}-[0-9]{6})$/; 
     if (re.test(txtNumber.value)==true) { 
      return 1; 
     } 
     else { 
      alert("Invalid Account Number"); 
      return 0; 
     } 

任何建议或指导,将不胜感激

有效号码:

12345678912(11位)

12-345-678912(11位本身由连字符)

INVALID NUMBERS parated:

1223(小于11位)

111111111111(大于11位)

123-23-678912(11位数,但不能正确分离,它应该是2个位数-3位数-6位)

+0

这不是重复的,因为我不问如何使用XX-XXX-XXXXXX模式验证数字。我问的是为什么我的正则表达式中只有一条规则起作用,另一条则不起作用。 – eddy

+0

对于看到这个问题的未来用户来说,它仍然是很好的信息,所以我会离开它。你不会有这种封闭的危险。 – aliteralmind

回答

4

作为|正则表达式运算符优先级是最低的,应该这样写:

/^(?:[0-9]{11}|[0-9]{2}-[0-9]{3}-[0-9]{6})$/ 

...,这样交替模式势必既开头和字符串的结尾。

目前的情况是在你的代码,模式检查在字符串,或序列的“两个数字,连字符,三个数字,连字符,六位数”在其末端年初的11位任何一个序列 - 但从来没有真正将规则绑定到两端。这很容易证明:

var patt = /^([0-9]{11})|([0-9]{2}-[0-9]{3}-[0-9]{6})$/; 
patt.test('acdbdfdsfsf22-333-666666'); // true 

一点题外话,因为你不需要捕获与分组表达什么,我已经与?:前面加上它。实际上,它可以进一步优化:

/^[0-9]{2}(?:[0-9]{9}|-[0-9]{3}-[0-9]{6})$/ 

...因为越少越好。但在这种情况下,我认为它确实无关紧要。


总之,这个问题可以用这两个模式进行说明:

/^a|b$/ 

此读为匹配任一a at the beginning of the string,或b at its end

/^(?:a|b)$/ 

此读为匹配beginning of the string,随后要么ab,随后the end of the string'。

+0

也许我没有解释清楚:(一个有效的数字可能是一个11位数字的序列(123456789123)或'两位数字,连字符,三位数字,连字符,六位数字(12-123-123456)的序列 – eddy

+0

与我所说的相矛盾?查看我的答案中的例子:没有给出的规则实际上是严格的,因为它们(因为'|'优先级)不适用于整个字符串 – raina77ow

+0

我的不好,应该是'12345678912' – eddy