2012-02-09 135 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 2012-02-09 16:30:23

+2

請注意,不需要第二個'+',因爲'match'將會返回所有的子表達式。 '.exec'每次只返回一個,所以它也不需要''''。 – pimvdb 2012-02-09 16:34:04

+3

最重要的是,像這兩個加法的嵌套量詞應該非常小心地使用,因爲它們容易導致[災難性的回溯](http://www.regular-expressions.info/catastrophic.html)。 – 2013-09-08 20:02:27

回答

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 2015-01-27 03:32:29

+3

@yeyo :更具體地說,它必須是相同的正則表達式對象,一個文字不會完成它 – Ryan 2015-01-27 05:12:20

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 2014-07-29 17:59:58

15

如果你的正則表達式是全局的,並且你正在捕獲,那麼你必須使用exec。匹配不會返回所有捕獲。

匹配適用於匹配時(非捕獲)。你運行它一次,它會給出所有匹配的數組。 (儘管如果正則表達式不是全局的,那麼匹配將顯示匹配,然後捕獲)

Exec是您在捕獲時使用的,每次執行時都會給出匹配,然後是捕獲。 (只有在正則表達式不是全局的情況下,匹配的行爲纔是完全匹配,然後是捕獲。

Exec的另一個用途是獲取匹配的索引或位置。當你有一個正則表達式的變量時,你可以使用.lastIndex並獲取匹配的位置。正則表達式對象具有.lastIndex,正則表達式對象就是您執行.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開始計數。通過減1來導出適當的索引。正如你所看到的,它給出了0 - lastIndex爲0 - 對於未找到)。

如果你想擴展匹配,你可以在捕獲時使用它,但是當正則表達式是全局的,而當你這樣做的時候,那麼數組的內容並不是全部匹配,但是完全匹配,然後是捕獲。

相關問題