Firefox和Chrome中不可靠的javascript正则表达式测试

时间:2010-07-20 15:21:19

标签: javascript jquery regex

我在Firefox 3.6和Chrome 6 dev上遇到了一个奇怪的javascript正则表达式问题。我正在开发一个大型表单入口网站,它使用jQuery进行一些基本的javascript验证。

$(document).ready(function() {
  $("tr[id^='" + BaseRowId + "rid']").each(function(){obj.WireRowEvents(this);});
}
var obj = {
  "WireRowEvents": function(row) {
    $("input[id$='Orgn']").blur(function() { obj.ValidateOrgn(this); }).blur();
    $("input[id$='Prog']").blur(function() { obj.ValidateProg(this); }).blur();
  },
  "ValidateOrgn": function(orgnId) { // ValiadateProg is the same as this
    var orgn = $(orgnId);            // function except it checks for a
    if (orgn.length == 0)            // length of 4 instead of 5.
      return;
    var orgnValue = orgn.val();
    if (orgnValue.length != 5) {
      if (orgnValue.length > 0) {
        orgn.addClass("invalid");
      } else {
        orgn.removeClass("invalid");
      }
    } else {
      if (/\d{5}/g.test(orgnValue)) { // This is the problem area
        orgn.removeClass("invalid");  // The above line is '/\d{4}/g' for prog.
      } else {
        orgn.addClass("invalid");
      }
    }
  }
}

使用上面的javascript(仅简化readyWireRowEvents函数,但ValidateOrgn方法完整无缺。正如您所看到的,Orgn的唯一要求是:长度为5个数字,Prog长度为4个数字。在Internet Explorer 7和8以及Safari 4.0.4中,上面的代码可以正常工作。

在Firefox和Chrome中,在页面加载时,Orgn和Prog被标记为无效,但仅在右侧。整行有两个Orgn和两个Prog输入(具有不同的ID,但以Orgn和Prog结尾)。左侧显示应该显示,但右侧显示为“无效”。

http://www.gibixonline.com/media/so/jquery-regex-initial.png

最好的部分是,您可以在文本框中单击并单击退出,有时(不是100%)它将正确验证。

http://www.gibixonline.com/media/so/jquery-regex-clicking.png

当单步执行Firebug中的ValidateOrgnValidateProg函数时,行if (/\d{5}/g.test(orgnValue))将返回false,这会导致它添加css类invalid。如果,那时,我复制相同的确切行并将其粘贴到控制台true按预期返回。再次,单击并单击将使其在有效和无效状态之间来回切换。

在Internet Explorer和Safari中它按预期工作,我无法在那里重现问题。

http://www.gibixonline.com/media/so/jquery-regex-correct.png

更新

这确实是全球旗帜问题。感谢Pointy的评论,我也设法简化了函数调用(它被一起hodpodged并标记为无论如何都要清理)。新方法现在是:

"ValidateOrgn": function (orgnId) {
  var orgn = $(orgnId);
  if (orgn.length == 0)
  return;

  // I don't want to mark it invalid if it's blank.
  if (orgn.val().length > 0) {
    if (/^\d{5}$/.test(orgn.val())) {
      orgn.removeClass("invalid");
    } else {
      orgn.addClass("invalid");
    }
  } else {
    orgn.removeClass("invalid");
  }
}

2 个答案:

答案 0 :(得分:3)

也许尝试将你的正则表达式放在一个单独的变量中,如下所示:

  //...
  var re = /^\d{5}$/; // using Pointy's comment, which I think is well-advised

  if (re.test(orgnValue)) { // This is the problem area
    orgn.removeClass("invalid");  // The above line is '/\d{4}/g' for prog.
  } else {
    orgn.addClass("invalid");
  }
  //...

答案 1 :(得分:2)

这是使用正则表达式对象时某些浏览器的已知问题,原因是lastIndex属性。您可以通过以下方式轻松复制它:

var r = /\d{5}/g;

alert(r.test('12345')); //true
alert(r.test('12346')); //false

在你的情况下,正则表达式被缓存,你看到相同的效果。一个简单的解决方案是重置正则表达式lastIndexr.lastIndex = 0,或者按照建议使用正则表达式,这不是问题。