2011-06-05 126 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