2012-06-13 80 views
12

可能重複:
Interesting test of Javascript RegExp
Regular expression test can't decide between true and false (JavaScript)爲什麼相同的RegExp行爲有所不同?

Example of issue。當內聯運行時,結果如我所料。但是,當作爲變量存儲時,它將跳過中間跨度元素。

// 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> 

鑑於: 我明白沒有理由要使用正規做這種比較,我也明白了很大的庫如jQuery的怎麼樣了。我也知道在這種情況下不需要g

我不明白爲什麼這兩種方法應該返回不同的結果。

+0

這只是個人偏好,但我認爲它會提高清晰度,使括號圍繞在正文上調用函數時具有標誌的正則表達式文字。 – JAB

+1

@apillers,你是對的。你尋找什麼來找到那些?我找不到要搜索的內容以獲得我之前的結果。 – Joe

+0

我騙了一點,並搜索'[javascript]正則表達式測試lastindex' - 我確信這個問題之前已經被問過,我知道答案會包含文字'lastIndex'。這是一個很好的例子,表明存在重複問題並不一定表明提問者是疏忽的;你已經提出了一個好的問題來解決一個難以搜索的問題。 – apsillers

回答

9

RegExp實例是有狀態,所以重用他們可能會導致意外的行爲。在這種情況下,這是因爲實例是global,這意味着:

正則表達式應該針對字符串中的所有可能匹配進行測試。

但是,這不是使用g造成的唯一區別。 From RegExp.test @ MDN

exec(或與之結合),test呼籲同全球正則表達式的情況下多次將提前超越了上一次的比賽。


Remove the g flag,或set lastIndex to 0(感謝,@zzzzBov)。

+3

或設置'lastIndex'爲'0' ... – zzzzBov

+0

@zzzzBov好點,編輯。 –

3

/g不是需要和不應該在這種情況下使用。

這些情況下的行爲不同,因爲在「內聯」情況下,循環的每次迭代都會重新創建正則表達式對象。在變量中創建一次,並在循環迭代之間保持其狀態(lastIndex)。

移動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; 
} 
+1

是的,我明白了。但是,爲什麼我很好奇知道。因爲'/toggler/g.test('toggler'); // true' – Joe

+1

@Joe,解釋。 – Qtax

+1

@Joe,你在問題中寫道*「我也知道'g'是需要的」*,這就是爲什麼我聲明它不是。 – Qtax

1

正則表達式維護一個名爲lastIndex的變量,它是開始下一個搜索的索引。從MDN

exec(或與之結合),test呼籲同全球正則表達式的情況下多次將提前超越了上一次的比賽。

當你定義爲每次迭代內嵌正則表達式,狀態丟失,lastIndex始終爲0,因爲你每次有一個新的正則表達式。如果將正則表達式保存爲可變,則lastIndex將保存爲最後一次匹配的結束位置,在這種情況下會導致在下一個字符串結尾處開始下一個搜索,導致匹配失敗。當第三次比較出現時,lastIndex已被重置爲0,因爲正則表達式知道它上次沒有結果。

相關問題