0

「cat、bat、sat、fat」の 2 番目の「.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 になるのでしょうか?

-_-

4

2 に答える 2

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/

于 2012-07-18T00:32:50.367 に答える
1

execグローバルな正規表現パターンでorを繰り返し呼び出すtestと、次の検索の開始位置が regexp オブジェクトlastIndexプロパティに格納されます。testまたはの各呼び出しはexec、プロパティを進め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 の両方を使用すると、次の検索の開始インデックスが失われます。

于 2012-07-18T00:52:36.720 に答える