2012-02-09 16 views
89

私はこれを実行した場合:RegExpのexec()関数とStringのmatch()関数の違いは何ですか?

/([^\/]+)+/g.exec('/a/b/c/d'); 

を、私はこの取得:

["a", "a"] 

をしかし、私はこの実行する場合:

'/a/b/c/d'.match(/([^\/]+)+/g); 

をそれから私はこれの期待される結果を得ます

["a", "b", "c", "d"] 

違いは何ですか?

+2

あなたはすべてのサブ選択を得るために 'exec'でループします。 – zzzzBov

+2

'match'はすでにすべての部分式を返すので、2番目の' + 'は不要です。 '.exec'は毎回1つだけを返すので、' + 'は必要ありません。 – pimvdb

+3

それに加えて、2つのプラスのようなネストされた量指定子は、[致命的なバックトラッキング](http://www.regular-expressions.info/catastrophic.html)に簡単につながるため、非常に慎重に使用する必要があります。 –

答えて

89

execグローバル正規表現は、ループ内で使用するためのもので、一致するすべての部分式を引き続き検索します。だから、:

var re = /[^\/]+/g; 
var match; 

while (match = re.exec('/a/b/c/d')) { 
    // match is now the next match, in array form. 
} 

// No more matches. 

String.matchはあなたのためにこれを実行し、キャプチャグループを破棄します。

+15

私はこの答えに追加する何かを持っていますが、このwhileのような正規表現のリテラルを 'while(match = /[^\/]+/g.exec('/a/b/c/ d ') 'または無限ループを作成します!MDNに明示されているようにhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec – yeyo

+3

@yeyo :具体的には、同じ正規表現オブジェクトでなければなりません。リテラルはそれを達成しません。 – Ryan

21

/regex/.exec()は最初の一致のみを返しますが、"string".match()は正規表現でgフラグを使用するとすべてを返します。

ここでは、exec,matchを参照してください。

54

一つの絵が

re_once = /([a-z])([A-Z])/ 
 
re_glob = /([a-z])([A-Z])/g 
 

 
st = "aAbBcC" 
 

 
console.log("match once="+ st.match(re_once)+ " match glob="+ st.match(re_glob)) 
 
console.log("exec once="+ re_once.exec(st) + " exec glob="+ re_glob.exec(st)) 
 
console.log("exec once="+ re_once.exec(st) + " exec glob="+ re_glob.exec(st)) 
 
console.log("exec once="+ re_once.exec(st) + " exec glob="+ re_glob.exec(st))

違いを参照してください...あなたが知っている、良いですか?

注:強調表示するには、グループを撮影し、通知(例えば:、A)が一致したパターン(例:AA)後に返され、それだけでマッチしたパターンではありません。

+0

私はこのようなコメントをすることはできませんが、それは素晴らしい答えです!私はそれを保存するつもりです。 – Joe

15

regexがグローバルでキャプチャしている場合は、execを使用する必要があります。マッチですべてのキャプチャが返されるわけではありません。

マッチは、マッチング(キャプチャしない)のときに効果的です。あなたは一度それを実行し、すべてのマッチの配列を与えます。 (ただし、正規表現がグローバルでない場合、マッチに続いてキャプチャが表示されます)

Execは、キャプチャ時に使用するもので、実行するたびにマッチ、その後のキャプチャが実行されます。 (正規表現がグローバルでない場合にのみ、完全一致とそれに続くキャプチャを与えるようにマッチします)。

もう1つExecと一緒に使用すると、一致するインデックスまたは位置が得られます。正規表現の変数がある場合は、.lastIndexを使用して一致の位置を取得できます。正規表現オブジェクトは.lastIndexを持ち、regexオブジェクトは.execを使用したものです。ドットの一致が文字列で行われ、正規表現を実行できなくなります。lastIndex

文字列には正規表現が渡されます。そして正規表現は、exec関数を持ち、文字列が渡されます

execを複数回実行します。一度実行すると一致する

キャプチャしていないときにはマッチを使用するのが良いし、キャプチャ時にはキャプチャを行うのに適しているのでより強力なexecを使うことができますが、キャプチャ時にマッチを使用した場合は、正規表現はグローバルではありませんが、正規表現がグローバルである場合にはキャプチャを表示しません。

> "azb".match(/a(z)b/); 
[ "azb", "z" ] 

> "azb".match(/a(z)b/g); 
[ "azb" ] 
> 

は、もう一つは、あなたがexecを使用する場合は、正規表現のために変数を使用した場合、その後、正規表現で呼ばれていますことに注意してくださいということです、あなたはより多くの電力を持って

ときあなたはマッチを得ることはありませんEXEC

> /./g.exec("abc") 
[ "a" ] 
> /./g.exec("abc") 
[ "a" ] 
> /./g.exec("abc") 
[ "a" ] 
> 
> /[a-c]/g.exec("abc") 
[ "a" ] 
> /[a-c]/g.exec("abc") 
[ "a" ] 
> 

> var r=/[a-c]/g 
> r.exec("abc") 
[ "a" ] 
> r.exec("abc") 
[ "b" ] 
> r.exec("abc") 
[ "c" ] 
> r.exec("abc") 
null 
> 

とexecとを使用しているとき、あなたは試合

> var r=/T/g 
> r.exec("qTqqqTqqTq"); 
[ "T" ] 
> r.lastIndex 
2 
> r.exec("qTqqqTqqTq"); 
[ "T" ] 
> r.lastIndex 
6 
> r.exec("qTqqqTqqTq"); 
[ "T" ] 
> r.lastIndex 
9 
> r.exec("qTqqqTqqTq"); 
null 
> r.lastIndex 
0 
> 
の「インデックス」を取得することができ、正規表現のための変数を使用するので、正規表現のための変数を使用していません

もしあなたがインデックスやキャプチャをしたいのであれば、execを使ってみてください。あなたが見ることができるように、 "インデックス"では "インデックス"は本当にn番目のものです。 1を引いて適切なインデックスを導出します。そして、あなたが見ることができるように、0 - lastIndexが0である - 見つからないため)を返します。

ストレッチマッチを行いたい場合は、キャプチャ時に使用することはできますが、正規表現がグローバルである場合には使用できません。また、正規表現を使用する場合は、配列の内容がすべて一致するわけではありません。キャプチャが後に続くフルマッチです。

関連する問題