Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to improve (eliminate too many tokens?) slow regexp in JavaScript?

I have function to bold part of line before colon.

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

and

//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>";
});

you can test it on jsfiddle: http://jsfiddle.net/damg7zuk/4/

Where I do a mistake? I can make word limitation inside the callback. Can it be done better in regex itself? Thank you for your trick.

like image 500
Václav Juchelka Avatar asked Dec 05 '14 12:12

Václav Juchelka


2 Answers

Your /^([^*:\n ]+ ?){1,10}:/gm regex exhibits catastrophic backtracking: You're nesting the + and the {1,10} repetition with (possibly) nothing in between. Fix this by making the blank that separates the groups compulsory to match:

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

or

/^[^*:\n ]+( [^*:\n ]+){0,9}:/gm
like image 161
Bergi Avatar answered Oct 31 '22 09:10

Bergi


js level can be so:

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>";
});
like image 28
websky Avatar answered Oct 31 '22 08:10

websky