regex - Snabbaste sättet att kontrollera om en sträng innehåller en annan delsträng i JavaScript?


Jag arbetar med ett prestandaproblem i JavaScript. Så jag vill bara fråga: vad är det snabbaste sättet att kontrollera om en sträng innehåller en annan delsträng (jag behöver bara ett booleskt värde)? Kan du vänligen ge ditt förslag och ett exempel på kodsnutt?

Svar #1

Du har tre möjligheter:

  1. Reguljärt uttryck:

     (new RegExp('word')).test(str)
     // or
     /word/.test(str)
    
  2. indexOf:

     str.indexOf('word') !== -1
    
  3. innehåller:

     str.includes('word')
    

Reguljära uttryck verkar vara snabbare (åtminstone i Chrome 10).

Prestandatest - kort höstack
Prestandatest - lång höstack

Det kan inte sägas med säkerhet vilken metod som är snabbare. Skillnaderna mellan webbläsarna är enorma. Medan indexOf verkar vara snabbare i Chrome 10, är indexOf i Safari 5 tydligt långsammare än någon annan metod.

Du måste se och prova själv. Det beror på dina behov. Till exempel är en icke skiftlägeskänslig sökning mycket snabbare med reguljära uttryck.

Uppdatering 2018:

Bara för att spara folk från att själva köra testerna, här är de aktuella resultaten för de vanligaste webbläsarna, procentandelarna anger prestandaökning jämfört med nästa snabbaste resultat (som varierar mellan webbläsarna):

Chrome: indexOf (~98% snabbare) <-- wow
Firefox: cachad RegExp (~18% snabbare)
IE11: cachad RegExp (~10% snabbare)
Edge: indexOf (~18% snabbare)
Safari: cachad RegExp (~0,4% snabbare)

Observera att cachad RegExp är: var r=new RegExp('simple'); var c=r.test(str); till skillnad från: /simple/.test(str)

Svar #2

Den snabbaste

  1. (ES6) inkluderar
    var string = "hello",
    substring = "lo";
    string.includes(substring);
  1. ES5 och äldre indexOf
    var string = "hello",
    substring = "lo";
    string.indexOf(substring) !== -1;

http://jsben.ch/9cwLJ

Svar #3

Fungerar det här för dig?

string1.indexOf(string2) >= 0

Redigera: Detta kanske inte är snabbare än ett RegExp om string2 innehåller upprepade mönster. I vissa webbläsare kan indexOf vara mycket långsammare än RegExp. Se kommentarer.

Redigera 2: RegExp kan vara snabbare än indexOf när strängarna är mycket långa och/eller innehåller upprepade mönster. Se kommentarer och @Felix svar.

Svar #4

I ES6 används includes()-metoden för att avgöra om en sträng kan hittas inom en annan sträng, och returnerar true eller false efter behov.

var str = 'To be, or not to be, that is the question.';

console.log(str.includes('To be'));       // true
console.log(str.includes('question'));    // true
console.log(str.includes('nonexistent')); // false

Här är jsperf mellan

var ret = str.includes('one');

Och

var ret = (str.indexOf('one') !== -1);

Som resultatet som visas i jsperf, verkar det som om båda presterar bra.

Relaterade artiklar