正则表达式有些奇怪

时间:2013-03-27 02:50:28

标签: javascript

说我有以下正则表达式代码:

var str = "{$ for ( var i = 0, len = O.length; i < len; i++ ) { $}";

var reg = /\{\$(.*?)\$\}/g;

console.log(reg.test(str));

console.log(reg.test(str));

console.log(reg.test(str));

为什么结果是True和False的交替?

3 个答案:

答案 0 :(得分:3)

docs

  

当您想知道是否在字符串中找到模式时,请使用test方法(类似于String.search方法);有关更多信息(但执行速度较慢),请使用exec方法(类似于String.match方法)。与exec(或与其结合使用)一样,在同一个全局正则表达式实例上多次调用的测试将超过上一个匹配。

为了说明正在发生的事情,我们可以使用exec并查看正在发生的事情。通过顺序:

  1. 原始字符串(真实)
    整个字符串匹配,评估为真。
  2. null(falsy)
    连续调用继续,所以由于第一个调用返回了整个结果,我们留下null
  3. 原始字符串(真实)
    模式返回开始并继续。
  4. 为了证明,run the following

    var str = '{$ for ( var i = 0, len = O.length; i < len; i++ ) { $}';
    var reg = /\{\$(.*?)\$\}/g;
    for (var i = 0; i < 3; i++){
        var result = reg.exec(str);
        console.log(result);
        console.log(!!result);
    }
    

答案 1 :(得分:2)

内部JavaScript RegExp s maintain state,包括匹配的最后一个索引等字段。因此,您可以在重用正则表达式时看到一些有趣的行为,如您给出的示例所示。

/g标志会导致它针对给定字符串的每次连续匹配返回true一次(在您的示例中恰好只有一个),之后它将返回{{ 1}}一次,然后重新开始。在每次调用之间,上述false属性将相应更新。

请考虑以下事项:

lastIndex

对战:

var str = "12";
var regex = /\d/g;

console.log(regex.test(str)); // true
console.log(regex.test(str)); // true
console.log(regex.test(str)); // false

答案 2 :(得分:0)

有趣的发现!我相信它与你的全局修饰符'/ g'有关。当您删除全局修饰符时,它似乎按预期工作。我不是正则表达专家;我只能假设.test()可以迭代$符号,即使它不应该匹配两次。