http://topic.youkuaiyun.com/u/20110111/00/5bc889c6-14b0-4297-bd6a-383c719ba1b2.html
问题的起源是上面的帖子,昨天晚上看到帖子的时候已经超过12:40了。没有时间去思考,给了个答案就匆匆睡了。初步诊断了IE7下的环视出现了BUG
早上起来就开始折腾这玩意,废话不多说,看看BUG到底出在什么地方吧
首先我把正则简化了问题,因为错误的不确定性,我试图删除各个地方以达到尽量展示错误的来源。最后得到的正则如下
/^(?=.*/d).{8,20}$/
这个时候测试依然错误。也可以检测出和环视有关系
给每个部分加上分组测试
/^(?=(.*)(/d))(.{8,20})$/
这个正则依然不具有任何意义,因为他找不到匹配,逐步调整
var s = "abc123123";
var reg = /^(?=(.*)(/d))(.+)$/;
alert(reg.exec(s));
测试结果完全正确,看不出和其他浏览器及正则原理有任何不同。由此可见环视中.*确实是贪婪匹配,/d也正常匹配的数字。
再做一次调整。
var s = "abc123123";
var reg = /^(?=(.*)(/d))(.{6,20})$/;
alert(reg.exec(s));
问题出现了
.*竟然匹配abc而非abc123123。难道说.*不是贪婪匹配么?不对啊,刚才的测试证明他确实是贪婪匹配啊。只能猜测.*影响了后面的匹配。
var s = "abc123123";
var reg = /^(?=(.*)(/d))(.{2,20})$/;
alert(reg.exec(s));
这次匹配的结果是.*匹配abc1231
/d匹配的是2
根据两次的测试,初步得出的结论是.*是贪婪匹配,但是环视中的匹配位置出现了错误。
.{6,20}的匹配证明了/d是没有问题的,因为/d虽然匹配了1,但是没有占有任何字符和位置,把字符1交还给了.{6,20}
由此可见。.*最大只能匹配到总长度减去.{2,20}的最小长度
引用下好奇的说法:
ie的预查和量词是有bug的。。。
实际上这里的
{6,18}
量词
它是从预查里的lastIndex开始计算的。
就是
a这个位置前面的那个位置,所以显然是false。
下面是我的解释:
它是从预查里的lastIndex开始计算的。 这里有点更正 是从预查的.*的lastIndex开始计算
比如.*/d 这个时候他不是从/d后面的position开始计算 而是.*的position开始计算
当后面的量词最小值为N的时候 .*被迫回溯到后面匹配所需的n个元素的position