140

ChromeまたはFirebugコンソールの場合:

reg = /ab/g
str = "abc"
reg.exec(str)
   ==> ["ab"]
reg.exec(str)
   ==> null
reg.exec(str)
   ==> ["ab"]
reg.exec(str)
   ==> null

execはどういうわけかステートフルであり、前回何を返したかによって異なりますか?それともこれは単なるバグですか?私はそれをいつも起こらせることはできません。たとえば、上記の「str」が「abc abc」の場合、それは発生しません。

4

3 に答える 3

259

JavaScriptRegExpオブジェクトはステートフルです。

正規表現がグローバルである場合、同じ正規表現オブジェクトでメソッドを呼び出すと、最後の一致の終わりを過ぎたインデックスから開始されます。

一致するものがなくなると、インデックスは0自動的にリセットされます。


手動でリセットするには、lastIndexプロパティを設定します。

reg.lastIndex = 0;

これは非常に便利な機能です。必要に応じて、文字列の任意の時点で評価を開始できます。ループ内の場合は、必要な数の一致後に評価を停止できます。


これは、ループで正規表現を使用するための一般的なアプローチのデモンストレーションです。ループ条件として割り当てを実行することにより、一致がなくなったときにexec戻るという事実を利用します。null

var re = /foo_(\d+)/g,
    str = "text foo_123 more text foo_456 foo_789 end text",
    match,
    results = [];

while (match = re.exec(str))
    results.push(+match[1]);

デモ:http: //jsfiddle.net/pPW8Y/


割り当ての配置が気に入らない場合は、たとえば次のようにループを作り直すことができます...

var re = /foo_(\d+)/g,
    str = "text foo_123 more text foo_456 foo_789 end text",
    match,
    results = [];

do {
    match = re.exec(str);
    if (match)
        results.push(+match[1]);
} while (match);

デモ:http: //jsfiddle.net/pPW8Y/1/

于 2012-07-13T19:53:49.950 に答える
27

MDNドキュメントから:

正規表現で「g」フラグを使用している場合は、execメソッドを複数回使用して、同じ文字列内の連続する一致を見つけることができます。これを行うと、検索は正規表現のlastIndexプロパティで指定されたstrのサブストリングから開始されます(テストではlastIndexプロパティも進められます)。

gフラグを使用しているためexec、最後に一致した文字列から最後に到達するまで(returns null)、最初からやり直します。


個人的に、私は逆に行きたいですstr.match(reg)

于 2012-07-13T19:55:10.323 に答える
13

複数の一致

正規表現にgフラグ(グローバル一致)が必要な場合は、lastIndexプロパティを使用してインデックス(最後の一致の位置)をリセットする必要があります。

reg.lastIndex = 0;

これは、発生するたびexec()停止するため、残りの部分で再度実行できるためです。この動作は、test()):にも存在します。

正規表現で「g」フラグを使用している場合は、execメソッドを複数回使用して、同じ文字列内の連続する一致を見つけることができます。これを行うと、検索は正規表現のlastIndexプロパティで指定されたstrのサブストリングから開始されます(テストはlastIndexプロパティも進めます)

シングルマッチ

一致する可能性のあるものが1つしかない場合は、フラグを省略してg正規表現を書き換えることができます。これは、インデックスが自動的ににリセットされるため0です。

于 2013-01-14T11:52:54.387 に答える