0

我想得到“cat, bat, sat, fat”中的第二个“.at”'index,程序是:

var text = "cat, bat, sat, fat";
var pattern = /.at/g;
var matches = pattern.exec(text);
var num = 2;
var i = 0;
while(pattern.test(text)){
  if(++i == num){
    alert(matches.index);
    break;
  }
  matches = pattern.exec(text);
}

正确的索引应该是 5,但是为什么我得到 10?

-_-

4

2 回答 2

2

您的问题是因为您对两者都使用相同的正则表达式,.test()并且.exec()期望状态不会受到影响,但是lastIndex由 the 推进,.test()因此在下一次.exec()发生时它是不正确的。要消除该问题,您可以删除.test()然后它可以工作(并且更有效):

var text = "cat, bat, sat, fat";
var pattern = /.at/g;
var num = 2, i = 0, matches;
while(matches = pattern.exec(text)){
  if(++i == num){
    alert(matches.index);
    break;
  }
}​

在这里工作演示:http: //jsfiddle.net/jfriend00/rbWQj/

于 2012-07-18T00:32:50.367 回答
1

当重复调用exectest在全局正则表达式模式上时,下一次搜索的起始位置存储在正则表达式对象lastIndex属性中。每次调用test或调用execlastIndex属性。考虑到这一点,让我们看看您的代码在做什么:

var text = "cat, bat, sat, fat";
var pattern = /.at/g;
var matches = pattern.exec(text); //goes over the first match at 0, lastIndex=3
var num = 2;
var i = 0;
while(pattern.test(text)){
  //first iteration: lastIndex=8 not 3, match at 5
  //second iteration: lastIndex=18, match at 15
  if(++i == num){
    //matches still has the match from 10
    alert(matches.index); //returns 10
    break;
  }
  matches = pattern.exec(text);
  //first iteration: lastIndex=13, match at 10
}

所以是的,在代码中同时使用 test 和 exec 会丢弃下一次搜索的起始索引。

于 2012-07-18T00:52:36.720 回答