2014-12-05 47 views
8

我有冒号前的粗体部分的功能。如何提高(消除太多令牌?)JavaScript中缓慢的regexp?

//Fast regex (time: 0) 
var colonRegex = /^[^*:\n]+:/gm; 

//Slow regex (time: 139) Limit by 10 words 
//var colonRegex = /^([^*:\n ]+ ?){1,10}:/gm; 
// I have issue with it when I want to apply replace to tens of divs (it freezes chrome) 

var bolded = str.replace(colonRegex, function(match) { 
    return "<b>"+match+"</b>"; 
}); 

你可以的jsfiddle测试:http://jsfiddle.net/damg7zuk/4/

我哪里错了吗? 我可以在回调内限制字数。 在正则表达式中它可以做得更好吗? 谢谢你的诀窍。

+0

我两者都超快使用LMDE和Firefox – 2014-12-05 12:57:13

+0

你为什么要使用回调:通过使分隔强制匹配组的空白解决这一问题?你不能使用'.replace(colonRegex,“$ 1”);'? (如果你在正则表达式中添加了一些括号:'/ ^([^ *:\ n] +:)/ gm'。)如果我将缓慢的正则表达式添加到你的小提琴中,它运行在“时间:34”冻结Chrome。 – nnnnnn 2014-12-05 12:57:16

+2

问题是你得到了灾难性的回溯。当冒号前有超过10个单词的行时,该模式将首先匹配这10个单词。然后它发现最后的冒号不匹配,所以它一次开始回溯一个字符,然后重新评估该模式,直到将它覆盖到一个单词,从而可以确定该模式不匹配根本就不在这条线上。 – Guffa 2014-12-05 13:12:24

回答

1

JS水平可以这样:

var bolded = str.replace(colonRegex, function(match) { 

    if (match.indexOf(".") > 0){ 
     match1 = match.slice(0,(match.indexOf(".")+1)); 
     match2 = match.slice(match.indexOf(".")+1); 

     match = match1+"<b>"+match2+"</b>"; 
     return match; 
    } 
    return "<b>"+match+"</b>"; 
}); 
2

/^([^*:\n ]+ ?){1,10}:/gm正则表达式展品catastrophic backtracking:你嵌套+{1,10}重复与之间(可能)没有。

/^([^*:\n ]+){0,9}[^*:\n ]+:/gm 
#   ^

/^[^*:\n ]+([^*:\n ]+){0,9}:/gm