日期:2014-05-17  浏览次数:20640 次

求兼容IE7,IE8的密码验证JS正则表达式: 必须包括数字、字母,长度8-20
在网上找了一个密码验证JS:密码必须包括数字、字母,长度8-20
写了一个测试代码

<script language="javascript">
var s = "abc123123";
var pattern = /^(?=.*\d.*)(?=.*[a-zA-Z].*).{8,20}$/;
alert(pattern.test(s));
</script>

在IE7下,总是弹出false,但在IE8下确弹出true

望有经验的哥们给予帮助,在下万分感谢!

------解决方案--------------------
^(?=.*\d.*)(?=.*[a-zA-Z].*).{8,20}$
这样理解

首先,判断^找到字符串第一个字符之前的位置。

然后来看第一个环视
(?=.*\d.*)
这里开始尝试查找后面满足条件的情况。因为是贪婪模式,并且.可以匹配任意的非换行符字符。所以这个环视会有大量的回溯。
对于
abc123123
会先由第一个.*匹配整个字符串,然后发现\d.*失配,发生回溯,正则表达式返回上一个匹配点,.*?匹配abc12312,继续尝试\d也符合,后面的.*因为前面表达式已经成立,这里虽然是贪婪捕获,但依然按照0次,捕获空。
结果为:
正则    捕获
.*     abc12312
\d     3
.*     <NULL>
所以,环视结果为true,而位置匹配到的则是最前面,a之前。

然后看第二个环视
(?=.*[a-zA-Z].*)
一样的,贪婪模式,.*就先匹配全部,然后回溯上一个捕获点,直到[a-zA-Z]匹配成功。
结果为:
正则       捕获
.*        ab
[a-zA-Z]  c
.*        123123

所以,这个也是匹配成功的,此时的位置依然是a前面的位置。
继续执行的是
.{8,20} 所以你根本没有做任何限制。

1楼科长的显然是对的。写法是很多的。
例如:
^(?!\D+$)(?![^a-zA-Z]+$)[a-zA-Z0-9]{8,20}$
------解决方案--------------------
如果不能出现空格之类的话
^(?!\D+$)(?![^a-zA-Z]+$)\S{8,20}$