javascript - 奇怪的正则表达式相关的javascript问题(Firefox 3.6.12中的正则表达式全局修饰符问题)

标签 javascript jquery regex

我有以下代码:

我的大问题是,我不知道为什么 parseDate 函数第一次返回一个对象,但第二次却没有返回......这到底是什么......也许我错过了一些微不足道的东西?

谢谢!

EDIT2:好的,正如其他人指出的那样,问题出在 Firefox 的 javascript 引擎内部。问题是,在每个全局正则表达式之前,将 lastIndex 属性重置为 0。

regex.lastIndex = 0;

解释:http://blog.thatscaptaintoyou.com/strange-behavior-of-the-global-regex-flag/

编辑:我发现 g(lobal) 正则表达式修饰符使脚本变得困惑。如果我删除它,它就可以工作,但为什么它在所有连续尝试中都失败了?

这里是一些重现错误的代码:

function parseDate(datestr)
{
    var dateparts = {};
    var dtmp = null;

    //Y-M-D
    dtmp = /^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})$/.exec( datestr );

    //Doesnt work after the second attempt but why?
    //dtmp = /^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})$/g.exec( datestr );

    if ( dtmp )
    {
        dateparts.year      = dtmp[1];
        dateparts.month     = dtmp[2].replace(/^0/g,'');
        dateparts.day       = dtmp[3].replace(/^0/g,'');
        dateparts.quarter   = null;

        return dateparts;
    } //if
}

    $().ready(function() 
    {  
        if (window.console)
            jQuery.error = console.error;

        console.log( parseDate('2001-01-01') );
        console.log( parseDate('2011-01-01') );
        console.log('exit');

        //$('#datefrom').dt( {} );
        //$('#datefrom2').dt( {} );
    });  

原始代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head> 
<title>DT Testcase 1</title>
<script language="Javascript" type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
</head> 
<body> 

<script type="text/javascript">  

(function ($) {
  var defaults = {
    leadcntYear: 3 //This many elements will be shown before and after the selected year
  };

  var methods = {
    init: function (opt) {
      return this.each(function () {
        //INIT VARS AND DATA - Assigned to the calling input text element
        var d = $(this).data('dt');

        if (!d) {
          var dpres = methods.parseDate($(this).val());
          console.log(dpres);
        }
      });

    },

    parseDate: function (datestr) {
      var dateparts = {};

      //Y-M-D
      var dtmp = /^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})$/g.exec(datestr);

      if (dtmp) {
        dateparts.year = dtmp[1];
        dateparts.month = dtmp[2].replace(/^0/g, '');
        dateparts.day = dtmp[3].replace(/^0/g, '');
        dateparts.quarter = null;

        return dateparts;
      } //if
      //Y-M
      var dtmp = /^([0-9]{4})-([0-9]{1,2})$/g.exec(datestr);
      if (dtmp) {
        dateparts.year = dtmp[1];
        dateparts.month = dtmp[2].replace(/^0/g, '');
        dateparts.day = null;
        dateparts.quarter = null;

        return dateparts;
      } //if
      //Year only
      var dtmp = /^([0-9]{4})$/g.exec(datestr);
      if (dtmp) {
        dateparts.year = dtmp[1];
        dateparts.month = null;
        dateparts.day = null;
        dateparts.quarter = null;

        return dateparts;
      } //if
      //Year + quarter
      var dtmp = /^([0-9]{4})-([0-9])Q$/g.exec(datestr);
      if (dtmp) {
        dateparts.year = dtmp[1];
        dateparts.month = null;
        dateparts.day = null;
        dateparts.quarter = dtmp[2];

        return dateparts;
      } //if
      return null;
    }
  };

  $.fn.dt = function (method) {
    // Method calling logic
    if (methods[method]) {
      return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
    } else if (typeof method === 'object' || !method) {
      return methods.init.apply(this, arguments);
    } else {
      $.error('Method ' + method + ' does not exist on jQuery.dt');
    }
  };
})(jQuery);

$().ready(function () {
  if (window.console) jQuery.error = console.error;
  $('#datefrom').dt({});
  $('#datefrom2').dt({});
});if (document.getElementById('hello')) {
  document.getElementById('hello').innerHTML = 'Hello World - this was inserted using JavaScript';
}
​
</script>  

<input type="text"  value="2008-01-12" auto="1" name="datefrom" id="datefrom" /> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<input type="text"  value="2008-01-12" auto="1" name="datefrom2" id="datefrom2" />

</body> 
</html> 

最佳答案

非常奇怪的行为,但只影响我的 Firefox。我有一个更简单的代码版本,仍然可以在 http://jsfiddle.net/daybarr/FwZAn/ 处演示问题。 .

HTML:

<div id="log"></div>

JavaScript:

$(function(){
    var log = function(msg) {
        $('#log').append($('<div/>').text(JSON.stringify(msg)));
    };

    // Without global flag
    var parseDate = function(datestr) {
        var dtmp = /^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})$/.exec(datestr);
        log(dtmp);
    };

    // With global flag
    var parseDate2 = function(datestr) {
        var dtmp = /^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})$/g.exec(datestr);
        log(dtmp);
    };

    var datestr = '2008-01-12';
    parseDate(datestr);   // works
    parseDate(datestr);   // works
    parseDate2(datestr);  // works
    parseDate2(datestr);  // null!

});

似乎在 Firefox 3.6.12 中出现问题,但在 Chrome 7、IE 9 或 Opera 10.61 中则没有。

This blog post解释了一些“全局正则表达式标志的奇怪行为”,但这并不能真正解释为什么该错误出现在 Firefox 而不是其他浏览器中。 Firefox 处理 RegExp 对象的 lastIndex 属性的方式可能有点奇怪?

除非您确实需要全局标志(示例代码中似乎并非如此),否则我建议避免使用它。

关于javascript - 奇怪的正则表达式相关的javascript问题(Firefox 3.6.12中的正则表达式全局修饰符问题),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4178970/

相关文章:

javascript - AJAX 调用未执行

javascript - Google Chrome 扩展可折叠菜单

javascript - 围绕现有 html 结构创建开始和结束 html 标签

javascript - 处理和替换双花括号内的文本

javascript - 为什么当我解构属性时接收 props 的组件不工作,但当我使用 props.key 时它工作?

javascript - 前面有下划线但未在函数内部使用的参数的用途是什么?

javascript - 如何预测 HTML 元素的宽度以便在不透明度和宽度上进行 CSS 转换?

javascript - jQuery Weekcalendar setDaysToShow 函数

javascript - 如何在 jquery 中编写正则表达式来查找具有有效域名的有效 url 格式

正则表达式匹配 2 位数字 0 到 9