2011-06-05 99 views
5

閱讀本SO post - Is there a version of JavaScript's String.indexOf() that allows for regular expressions?),我思考,其中,在txt運行尋找最後一個(最大的)空白組快(或執行下列兩種功能,他們可以忽略不計的運行時間差)正則表達式VS while循環

 
(function(str) 
{ 
    var result = /\s+(?!.*\s+)/.exec(str); 
    return ((result)? result.index : -1); 
})(txt); 

 
(function(str) 
{ 
    var regex = /\s+/g; 
    var result; 
    var index = -1; 
    while(result = regex.exec(str)) 
    { 
     index = result.index; 
    } 
    return index; 
})(txt); 

簡要地說,首先使用一個正則表達式表達式來尋找那些後面沒有任何其他空白組一個空白組,並且所述第二使用while循環。

任何有關這個問題的幫助是非常感謝。

+1

您可以隨時[嘗試兩種方法,看看!](http://jsperf.com) – Pointy 2011-06-05 14:41:58

+1

你的第二個功能是錯誤的。它需要'index = result.index'而不是'index + = result.index'。 – Gumbo 2011-06-05 14:56:46

+0

我的方法總是做最簡單的或者最明智的一個,讓專家們優化編譯器。總體而言,您可以瞭解哪種方法最快,並且可以使用它,但是您必須檢查所有瀏覽器和整體語言運行時變化,並且始終進行優化,因此現在最快的速度可能是後者中速度最慢的,因此請讓專家處理優化,除非你特別有困難。 – Jonathon 2011-06-05 16:04:31

回答

2
(function(str) 
{ 
    var result = /\s+(?!.*\s+)/.exec(str); 
    return ((result)? result.index : -1); 
})(txt); 

已損壞。它將匹配" \n",因爲.不匹配所有空格字符。具體而言,它與\s匹配的空格字符"\r\n\u2028\u2029"不匹配。

如果你想一個好辦法,在txt匹配最後一個(最大的)空白組,請使用以下RegExpString.prototype.search

var indexOfStartOfLastWhitespaceGroup = str.search(/\s+\S*$/); 

要得到結束索引,你不能使用.lastIndex屬性正則表達式,因爲它包含\S*部分。你可以再次使用.search

if (indexOfStartOfLastWhitespaceGroup >= 0) { 
    var indexOfEndOfLastWhitespaceGroup = str.search(/\S*$/); 
    ... 
} 

我思考這些看起來最後(最大)空白組TXT運行速度以下兩個函數(或他們有可以忽略不計的運行時間差)

對於小字符串的結果可能可以忽略不管你使用什麼(正確)的方法。對於大字符串,遍歷整個字符串將會很昂貴,所以最好的辦法是使用一個正則表達式,該表達式在最後停留,即有$作爲最後一個標記,並且沒有^。解釋器可能會浪費時間進行全字符串搜索,只有右側錨定的正則表達式,但我相信大多數都會執行此簡單優化。

這是我在squarefree shell下得到的。

var s = ''; 
for (var i = 10000; --i >= 0;) s += 'abba'; 
s += 'foo'; 
var t0 = Date.now(); for (var i = 100; --i >= 0;) /foo$/.test(s); var t1 = Date.now(); 
var t2 = Date.now(); for (var i = 100; --i >= 0;) /abbafoo/.test(s); var t3 = Date.now(); 
[t1 - t0, t3 - t2] 
// emits [1, 8] 

最後,你應該知道,\s並不總是意味着對所有解釋同樣的事情。​​它測試IE 6上是否爲空格(認爲 )爲空格,但在大多數其他瀏覽器的解釋器(對IE 7+不確定)上是否爲真。

+0

非常感謝你;這是非常豐富的。 – knight 2011-06-08 00:52:20

1

您可以使用jsPerf來比較不同JavaScript片段的性能。我創建one that uses your two variants and this one by me

function(str) { 
    var parts = str.split(/(?=\s+)/); 
    return parts.length === 1 ? -1 : str.length - parts[parts.length-1].length; 
} 

它基本上在分割利用先行斷言本場比賽的位置的字符串。如果找不到匹配項,split返回一個只有一個項目的數組;否則從字符串的總長度中減去最後一部分的長度以獲得最後匹配的索引。


更新我已經調整了功能一點點,現在我們已經獲得了一些完全不同的results相比previous benchmark。現在使用/\s+(?!\S+\s+)/代替/\s+(?!.*\s+)/的第一個功能似乎是最快的。

+0

我在想你的代碼,我不知道爲什麼它比我想的要快得多。這是爲什麼? – knight 2011-06-08 22:18:52