javaScript RegExp第二个索引

javaScript RegExp the second index

本文关键字:索引 第二个 RegExp javaScript      更新时间:2023-11-23

我想在"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呢?

-_-

您的问题是,您对.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/

在全局正则表达式模式上重复调用exectest时,下一次搜索的起始位置存储在正则表达式对象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会打乱下一次搜索的起始索引。