12

重複の可能性:
Javascript RegExpの興味深いテスト
正規表現テストでtrueとfalseのどちらかを判断できない(JavaScript)

問題の例。インラインで実行した場合、結果は私が期待するとおりです。ただし、変数として格納される場合は、ミドルスパン要素をスキップします。

// Inline RegExp
function getToggleClasses() {
  var toggler = [],
      elements = document.getElementsByTagName("*"),
      i=0,
      len = elements.length;

  for (i; i < len; i++) {
    if (/toggler/g.test(elements[i].className)) {
      toggler.push(elements[i]);
    }
  }

  document.getElementById('results').innerHTML += "<br />Inline: " + toggler.length;
}

// Variable
function getToggleClasses2() {
  var toggler = [],
      elements = document.getElementsByTagName("*"),
      tester = /toggler/g,
      i=0,
      len = elements.length;

  for (i; i < len; i++) {
    if (tester.test(elements[i].className)) {
      toggler.push(elements[i]);
    }
  }

  document.getElementById('results').innerHTML += "<br />Variable: " + toggler.length;
}
​

マークアップ:

<span class="toggler">A</span>
<span class="toggler">B</span>
<span class="toggler">C</span>

与えられた:私は、この比較を行うためにRegExpを使用する理由がないことを理解しています。また、jQueryなどのライブラリがどれほど優れているかも理解しています。gこの場合、は必要ないことも知っています。

これらの2つのメソッドが異なる結果を返す必要がある理由を理解できません。

4

3 に答える 3

9

RegExpインスタンスはステートフルであるため、それらを再利用すると予期しない動作が発生する可能性があります。この特定のケースでは、インスタンスがグローバルであるためです。つまり、次のようになります。

正規表現は、文字列内のすべての可能な一致に対してテストする必要があります。

ただし、を使用した場合の違いはそれだけではありませんg@ MDNからRegExp.test

と同様にexec(またはそれと組み合わせて)、test同じグローバル正規表現インスタンスで複数回呼び出されると、前の一致を超えて進みます。


gフラグを削除するか(thanks、 @ zzzzBov )に設定lastIndex0ます。

于 2012-06-13T19:34:54.017 に答える
3

/g不要であり、この場合は使用しないでください。

「インライン」の場合、ループの反復ごとに正規表現オブジェクトが再作成されるため、これらの場合の動作は異なります。lastIndex変数内にある間、変数は1回作成され、ループの反復間でその状態()を保持します。

varをループに移動すると、同じ結果が得られます。

// Variable
function getToggleClasses2() {
  var toggler = [],
      elements = document.getElementsByTagName("*"),
      i=0,
      len = elements.length;

  for (i; i < len; i++) {
    var tester = /toggler/g;
    if (tester.test(elements[i].className)) {
      toggler.push(elements[i]);
    }
  }

  document.getElementById('results').innerHTML += "<br />Variable: " + toggler.length;
}
于 2012-06-13T19:33:03.300 に答える
1

正規表現lastIndexは、次の検索を開始するためのインデックスである、と呼ばれる変数を維持します。MDNから:

と同様にexec(またはそれと組み合わせて)、test同じグローバル正規表現インスタンスで複数回呼び出されると、前の一致を超えて進みます。

反復ごとにインライン正規表現を定義すると、状態は失われ、lastIndex毎回新しい正規表現があるため、常に0になります。正規表現を検証可能に保持すると、lastIndexは最後の一致の終了位置として保存されます。この場合、次の検索は次の文字列の最後で開始され、一致に失敗します。3番目の比較lastIndexが行われると、正規表現は前回結果が得られなかったことを認識しているため、は0にリセットされています。

于 2012-06-13T19:42:00.620 に答える