2010-05-11 76 views
3

在我的對象中有funciton被定期調用。javascript string exec奇怪的行爲

parse : function(html) 
{ 
    var regexp = /...some pattern.../ 
    var match = regexp.exec(html); 
    while (match != null) 
    { 
     ... 
     match = regexp.exec(html); 
    } 
    ... 
    var r = /...pattern.../g; 
    var m = r.exec(html); 
} 

用不變的html m返回null對方的呼叫。讓我們說

parse(html);// ok 
parse(html);// m is null!!! 
parse(html);// ok 
parse(html);// m is null!!! 
// ...and so on... 

是那裏有html被重置任何指數或somrthing ...我真的很困惑。爲什麼match總是返回正確的結果?

回答

3

當處理具有全局g標誌的模式並且使用exectest方法時,這是一種常見行爲。

在這種情況下RegExp對象將跟蹤lastIndex的其中一個匹配的結果,然後在隨後的匹配,將開始從lastIndex而不是從0

編輯開始:響應於您的評論,爲什麼不,當你再次調用功能RegExp對象被重新創建:

這是正則表達式文字描述的行爲,讓我報價牛逼他規格:

§ 7.8.5 - Regular Expression Literals

...

含程序或函數的評價開始之前,創建對象。對文字的評估產生了對該對象的引用;它不會創建一個新的對象。

....

你可以做一個簡單的證明:

function createRe() { 
    var re = /foo/g; 
    return re; 
} 

createRe() === createRe(); // true, it's the same object 

你可以肯定的是同一個對象,因爲在程序「兩個正則表達式文字評估到正則表達式對象,即使兩個文字的內容完全相同,它們也不會互相比較爲===,例如:

/foo/ === /foo/; // always false... 

但是,所有瀏覽器都會遵守此行爲,但IE瀏覽器不會這樣做,因爲IE每次都會初始化新的RegExp對象。

+0

是的,我懷疑這樣的事情,但這些正則表達式變量沒有被gc-ed和重置?我相信每次我調用parse()時,都應該初始化新範圍。 – Pablo 2010-05-11 02:34:19

+0

@Michael,看看我的編輯... – CMS 2010-05-11 04:41:41

1

要避免這種行爲,因爲它可能會在這種情況下是必要的,簡單地設置

var r = /...pattern.../g; 
var m = r.exec(html); 
r.lastIndex=0; 

這爲我工作。