关于javascript:regex vs while循环

regex vs while loops

在阅读本文时-是否有允许正则表达式的javascript的string.indexof()版本?我考虑以下两个函数中的哪一个查找txt中最后一个(最大的)空白组运行得更快(或者它们的运行时差异可以忽略不计)

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

1
2
3
4
5
6
7
8
9
10
11
(function(str)
{
   var regex = /\s+/g;
   var result;
   var index = -1;
   while(result = regex.exec(str))
   {
       index = result.index;
   }
   return index;
})(txt);

简单地说,第一个使用regex表达式查找后面没有任何其他空白组的空白组,第二个使用while循环。

对于这件事的任何帮助都非常感谢。


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

被打破了。它将匹配"
"
,因为.不匹配所有空格字符。具体来说,它不匹配与\s匹配的空格字符"

\u2028\u2029"。

如果你想找到一个很好的方法来匹配txt中最后一个(最大的)空白组,请将下面的RegExpString.prototype.search一起使用:

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

要获取结束索引,不能使用正则表达式的.lastIndex属性,因为它包含\S*部分。不过,您可以再次使用.search

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

I ponder which of the following two functions that look for the last (largest) whitespace group in txt run faster (or do they have negligible run-time difference)

对于小字符串,无论使用什么(正确的)方法,结果都可能忽略不计。对于大型字符串,对整个字符串进行迭代将非常昂贵,因此您最好使用一个固定在末尾的正则表达式,即使用$作为最后一个标记,而不使用^。当只有右锚定的regex存在时,解释器可能会浪费时间进行完整的字符串搜索,但我相信大多数解释器都会进行这种简单的优化。

这就是我在铬合金下得到的方形外壳。

1
2
3
4
5
6
7
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并不总是对所有口译员都意味着相同的事情。/\s/.test("\xA0")测试非中断空格(认为 是一个空格)在IE 6上是错误的,但在大多数其他浏览器的解释程序上是正确的(不确定IE 7+)。


可以使用JSPerf比较不同javascript代码段的性能。我已经创建了一个使用您的两个变体的变体,这一个由我自己创建:

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

它基本上使用先行断言在匹配位置拆分字符串。如果找不到匹配项,split返回一个只有一个项的数组;否则,最后一部分的长度将从字符串的总长度中减去,得到最后一个匹配项的索引。

更新我对函数做了一些调整,现在我们得到了一些与前一个基准完全不同的结果。现在,第一个使用/\s+(?!\S+\s+)/而不是/\s+(?!.*\s+)/的函数似乎是最快的。