javaScript RegExp第二个索引

时间:2012-07-17 23:57:38

标签: javascript regex

我希望获得“cat,bat,sat,fat”中的第二个“.at”'索引,该程序是:

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,请?

-_-

2 个答案:

答案 0 :(得分:2)

您的问题是因为您对.test().exec()使用相同的正则表达式并期望状态不受影响,但lastIndex.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/

答案 1 :(得分:1)

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

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会抛弃下一个搜索的起始索引。