正则表达式与while循环

5

1
你可以尝试这两种方法并查看结果!(http://jsperf.com) - Pointy
1
你的第二个函数是错误的。它应该是index = result.index而不是index += result.index - Gumbo
我的方法始终是选择最简单或者至少是最合理的一个,然后让专家来优化编译器。总体而言,你可以找出目前最快的方法并使用它,但你需要检查所有浏览器和整个语言的运行时变化,并且一直在进行优化,所以现在最快的可能会变得比较慢,因此除非你明确遇到了问题,否则还是让专家来处理优化。 - Jonathon
谢谢!我修改了第二个函数,现在它是正确的。 - knight
2个回答

3
(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中最后(最大)的空格组,哪一个运行更快(或者它们在运行时有可忽略的差异)。
对于小字符串而言,无论你使用哪种(正确的)方法,结果都可能是可以忽略不计的。然而,对于大字符串而言,遍历整个字符串将会非常耗费时间,所以您最好使用正则表达式,该正则表达式以结尾为锚点,即最后一个标记为$并且其中没有^。当存在仅限右侧的锚定正则表达式时,解释器可能会浪费时间执行完整的字符串搜索,但我相信大多数解释器都会进行这种简单的优化。
这是我在chrome下的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的含义并不总是相同的。/\s/.test("\xA0")测试非断行空格(即 )是否为空格在IE 6上为false,在大多数其他浏览器的解释器上为true(不确定IE 7+如何)。


1

你可以使用jsPerf来比较不同JavaScript代码片段的性能。我创建了一个使用你的两个变量和我的代码的示例

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+)/的第一个函数似乎是最快的。


我在思考你的代码,但我不知道为什么它比我想到的两个代码要快那么多。这是为什么? - knight

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接