8

我很困惑这怎么可能......

var matcher = new RegExp("d", "gi");
matcher.test(item)

上面的代码包含以下值

item = "Douglas Enas"
matcher = /d/gi

然而,当我背靠背运行 matcher.test 函数时,我在第一次运行时得到 true,在第二次运行时得到 false。

matcher.test(item) // true
matcher.test(item) // false

如果我使用正则表达式文字,例如

/d/gi.test("Douglas Enas") 

并在chrome中背靠背运行它两次我都得到了真实的结果。对此有解释吗?

在 chrome 控制台中使用构造函数创建正则表达式对象的背靠背运行示例

matcher = new RegExp("d","gi")
/d/gi

matcher.test("Douglas Enas")
true

matcher.test("Douglas Enas")
false

matcher
/d/gi

在文字上使用背靠背调用的示例

/d/gi.test("Douglas Enas")
true

/d/gi.test("Douglas Enas")
true

这个问题的原因是因为使用 RegExp 构造函数和针对值列表的测试函数我失去了匹配......但是使用文字我得到了我期望的所有值

更新

                        var suggestions = [];

                        ////process response  
                        $.each(responseData, function (i, val)
                        {
                            suggestions.push(val.desc);
                        });


                        var arr = $.grep(suggestions, function(item) {
                            var matcher = new RegExp("d", "gi");
                            return matcher.test(item);
                        });

在闭包内移动匹配器的创建包括丢失的结果。“d”实际上是一个动态创建的字符串,但为了简单起见,我使用了“d”。我仍然不确定现在每次进行测试时创建一个新表达式,当我迭代建议数组时会无意中排除结果仍然有点令人困惑,并且可能与匹配测试的进步有关

4

3 回答 3

10

来自RegExp.test()

test在同一个全局正则表达式实例上多次调用将超过上一次匹配。

所以基本上当你有一个实例时RegExp,每次调用都会test推进匹配器。一旦你找到了第一个d,它就会超越它并尝试找到另一个 d。好吧,没有了,所以它返回false

另一方面,当你这样做时:

/d/gi.test("Douglas Enas") 

RegExp您每次都在现场创建一个新实例,因此它总是会首先找到该实例d(并因此返回true)。

于 2012-11-21T19:25:30.557 回答
0

根据 Mozilla 开发者网络,

与 exec (或与它结合使用)一样,在同一个全局正则表达式实例上多次调用 test 将超过上一次匹配。

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/test

于 2012-11-21T19:26:36.390 回答
0

我找不到链接 ATM,但我记得,这是该test方法与模式结合的一个已知问题g:匹配位置不会以某种方式“被遗忘”。要么放弃全局标志和/或使用该.match方法,它就会正常工作。

于 2012-11-21T19:29:41.447 回答