有人可以解释为什么RegExp.test会以这种方式表现吗?

时间:2017-08-24 11:55:10

标签: javascript node.js

  

注意:我在现实生产应用程序中遇到了这个问题。虽然我能够解决它,但遗憾的是,我不明白为什么它的表现如此。

我有这个正则表达式

// Notice global modified at the end.
const regexExp = /(\d{4})-(\d{2})-(\d{2})T((\d{2}):(\d{2}):(\d{2}))\.(\d{3})Z/g;

// Array of same string 6 times.
[
  '{"ApplicationDate.Time.DateTime":{"$gte":"2017-08-14T11:27:26.034Z","$lt":"2017-08-24T11:27:26.034Z"}}',
  '{"ApplicationDate.Time.DateTime":{"$gte":"2017-08-14T11:27:26.034Z","$lt":"2017-08-24T11:27:26.034Z"}}',
  '{"ApplicationDate.Time.DateTime":{"$gte":"2017-08-14T11:27:26.034Z","$lt":"2017-08-24T11:27:26.034Z"}}',
  '{"ApplicationDate.Time.DateTime":{"$gte":"2017-08-14T11:27:26.034Z","$lt":"2017-08-24T11:27:26.034Z"}}',
  '{"ApplicationDate.Time.DateTime":{"$gte":"2017-08-14T11:27:26.034Z","$lt":"2017-08-24T11:27:26.034Z"}}',
  '{"ApplicationDate.Time.DateTime":{"$gte":"2017-08-14T11:27:26.034Z","$lt":"2017-08-24T11:27:26.034Z"}}',
]
.forEach((i) => console.log(regexExp.test(i)));

    // This would print
    // true
    // true
    // false -> Why?
    // true
    // true
    // false -> why?

您可以点击Run Code snippet来运行代码。 令我感到困惑的是,为什么每false时间都会测试3rd

以下两种解决方案往往有效。

  1. Defining the Expression inside the forEach block.
  2. // Array of same string 6 times.
    [
      '{"ApplicationDate.Time.DateTime":{"$gte":"2017-08-14T11:27:26.034Z","$lt":"2017-08-24T11:27:26.034Z"}}',
      '{"ApplicationDate.Time.DateTime":{"$gte":"2017-08-14T11:27:26.034Z","$lt":"2017-08-24T11:27:26.034Z"}}',
      '{"ApplicationDate.Time.DateTime":{"$gte":"2017-08-14T11:27:26.034Z","$lt":"2017-08-24T11:27:26.034Z"}}',
      '{"ApplicationDate.Time.DateTime":{"$gte":"2017-08-14T11:27:26.034Z","$lt":"2017-08-24T11:27:26.034Z"}}',
      '{"ApplicationDate.Time.DateTime":{"$gte":"2017-08-14T11:27:26.034Z","$lt":"2017-08-24T11:27:26.034Z"}}',
      '{"ApplicationDate.Time.DateTime":{"$gte":"2017-08-14T11:27:26.034Z","$lt":"2017-08-24T11:27:26.034Z"}}',
    ]
    .forEach((i) => {
      const regexExp = /(\d{4})-(\d{2})-(\d{2})T((\d{2}):(\d{2}):(\d{2}))\.(\d{3})Z/g;
      console.log(regexExp.test(i))
    });
    
        // This would print
        // true
        // true
        // true -> Yay!!
        // true
        // true
        // true -> Yay!!

    我知道为什么会这样,因为基本上每个块范围都会创建新的正则表达式。即对于每个循环,创建一个新的正则表达式,因此相同的对象永远不会用于第二次调用。

    方法2:Use i modifier instead of g modified

    // Notice global modified at the end.
    const regexExp = /(\d{4})-(\d{2})-(\d{2})T((\d{2}):(\d{2}):(\d{2}))\.(\d{3})Z/i;
    
    // Array of same string 6 times.
    [
      '{"ApplicationDate.Time.DateTime":{"$gte":"2017-08-14T11:27:26.034Z","$lt":"2017-08-24T11:27:26.034Z"}}',
      '{"ApplicationDate.Time.DateTime":{"$gte":"2017-08-14T11:27:26.034Z","$lt":"2017-08-24T11:27:26.034Z"}}',
      '{"ApplicationDate.Time.DateTime":{"$gte":"2017-08-14T11:27:26.034Z","$lt":"2017-08-24T11:27:26.034Z"}}',
      '{"ApplicationDate.Time.DateTime":{"$gte":"2017-08-14T11:27:26.034Z","$lt":"2017-08-24T11:27:26.034Z"}}',
      '{"ApplicationDate.Time.DateTime":{"$gte":"2017-08-14T11:27:26.034Z","$lt":"2017-08-24T11:27:26.034Z"}}',
      '{"ApplicationDate.Time.DateTime":{"$gte":"2017-08-14T11:27:26.034Z","$lt":"2017-08-24T11:27:26.034Z"}}',
    ]
    .forEach((i) => console.log(regexExp.test(i)));
    
        // This would print
        // true
        // true
        // true -> Yay!!
        // true
        // true
        // true -> Yay!!

    为什么会发生这种情况,

    1. 为什么方法2有效?

    2. 当我使用i修饰符时,为什么它有效?为什么它不适用于g修饰符?

    3. 为什么每次3rd测试?为什么不4th5thany random测试?

    4. 似乎在使用g修饰符改变RegExp实例时,为什么会这样?

      如果有人能对这个问题有所了解,我真的很感激。

      提前致谢。

0 个答案:

没有答案