Václav Juchelka
Václav Juchelka

Reputation: 81

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.

Upvotes: 8

Views: 107

Answers (3)

Bergi
Bergi

Reputation: 665554

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

Upvotes: 2

websky
websky

Reputation: 3172

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

Upvotes: 1

vks
vks

Reputation: 67998

^(?:(?=([^*:\n ]+[ ]?))\1){0,10}:

Try this.See demo.

https://regex101.com/r/kX9kT1/1

Upvotes: 0

Related Questions