regex.test VS string.match, um festzustellen, ob eine Zeichenfolge mit einem regulären Ausdruck übereinstimmt

287

Oft verwende ich die Zeichenfolgenfunktion match, um festzustellen, ob eine Zeichenfolge mit einem regulären Ausdruck übereinstimmt.

if(str.match(/{regex}/))

Gibt es einen Unterschied zwischen diesen:

if (/{regex}/.test(str))

Sie scheinen das gleiche Ergebnis zu geben?

Gdoron unterstützt Monica
quelle
4
Dies sind die besten Tests, die Sie finden werden jsperf.com/regexp-test-vs-match-m5
ajax333221
@ ajax333221. Danke für den jsperf, aber ich bin mir nicht sicher, ob es ein guter ist. Die Regex-Übereinstimmung unter Verwendung einer Übereinstimmungsgruppe, die beim Suchen eines booleschen Werts nicht benötigt wird.
Gdoron unterstützt Monica

Antworten:

440

Grundlegende Verwendung

Lassen Sie uns zunächst sehen, was jede Funktion tut:

regexObject . test ( String )

Führt die Suche nach einer Übereinstimmung zwischen einem regulären Ausdruck und einer angegebenen Zeichenfolge aus. Gibt true oder false zurück .

Zeichenfolge . Übereinstimmung ( RegExp )

Wird verwendet, um die Übereinstimmungen abzurufen, wenn eine Zeichenfolge mit einem regulären Ausdruck abgeglichen wird. Gibt ein Array mit den Übereinstimmungen zurück oder nullwenn es keine gibt.

Da nullbewertet zu false,

if ( string.match(regex) ) {
  // There was a match.
} else {
  // No match.
} 

Performance

Gibt es einen Leistungsunterschied?

Ja . Ich habe diese kurze Notiz auf der MDN-Site gefunden :

Wenn Sie wissen müssen, ob eine Zeichenfolge mit einem regulären Ausdruck regexp übereinstimmt, verwenden Sie regexp.test (Zeichenfolge).

Ist der Unterschied signifikant?

Die Antwort lautet noch einmal JA ! Diese von mir zusammengestellte jsPerf zeigt, dass der Unterschied je nach Browser ~ 30% - ~ 60% beträgt :

Test gegen Match |  Leistungstest

Fazit

Verwenden .testSie diese Option, wenn Sie eine schnellere boolesche Prüfung wünschen. Verwenden Sie .matchdiese Option , um alle Übereinstimmungen abzurufen, wenn Sie das gglobale Flag verwenden.

Gdoron unterstützt Monica
quelle
5
Kein Wunder, denn die String-Funktion muss die Dinge umdrehen und dann das Array erstellen, wenn es eine Übereinstimmung gibt. Sieht so aus, als würde ich weiter verwenden .test(). :)
22
Meine zwei Cent: Leistung wird überbewertet. Beide Optionen können im Flackern eines Monitors ~ 15.000 Vorgänge ausführen. Wenn Sie also nicht clientseitig Bulk-Regex ausführen, ist die Geschwindigkeit nicht relevant. Natürlich ist 'test' logischerweise die richtige Funktion, wenn Sie nach einem booleschen Ergebnis suchen. Danke für das Q / A BTW.
David Gilbertson
2
Interessanterweise ist der Test mit dem obigen jsPerf-Test (Chrome 41, OSX) 41% langsamer als der Match für mich.
Benjie
1
@AlexShilman indexOf ist schneller (aber nicht viel) als der Test gemäß diesem stackoverflow.com/questions/183496/… (Sie würden erwarten, dass es schneller ist).
Podperson
1
Eine Sache, die Sie hier beißen könnte (es hat mein Team kürzlich gebissen): Wenn Sie das 'g'-Flag auf Ihrem Regex verwenden und eine neue Instanz erstellen (dh über neues RegExp (<regex_str>,' g ')) und Sie das wiederverwenden Zum Beispiel ist das Ausführen von "test" statusbehaftet, dh es werden unterschiedliche Ergebnisse zurückgegeben, wenn es mehrmals ausgeführt wird. Weitere Informationen finden Sie unter developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .
Davertron
118

Vergessen Sie nicht, die globale Flagge in Ihrem regulären Ausdruck zu berücksichtigen:

var reg = /abc/g;
!!'abcdefghi'.match(reg); // => true
!!'abcdefghi'.match(reg); // => true
reg.test('abcdefghi');    // => true
reg.test('abcdefghi');    // => false <=

Dies liegt daran, dass Regexp den lastIndex verfolgt, wenn eine neue Übereinstimmung gefunden wird.

gtournie
quelle
21
Ich habe nur mit dem Kopf geschlagen, als ich sah, dass mein regex.test () zufällig "wahr", dann "falsch" und dann "wahr" protokollierte ... danke!
Adriendenat
7
Ich denke, das ist die bessere Antwort. Es erklärt, dass sie nicht das gleiche Ergebnis liefern und dass reg.test () eine gefährliche Gefahr darstellt. Für mich ist string.match () die klare Wahl. Leistung war für mich nie ein Problem.
James
2
Das ist wichtig! Verrückt werden, um herauszufinden, warum jedes andere Ergebnis fehlte ... als Referenz für alle anderen, die dies finden: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Dan
2
Wenn Sie genauso verwirrt sind wie ich, lesen Sie stackoverflow.com/q/1520800/3714913 . Es gibt auch String.prototype.search () , der einen Index zurückgibt, aber dieses Problem nicht hat, soweit ich das beurteilen kann.
Nateowami
3
Nur neugierig, wozu eine globale Flagge gut ist .test()? .test()Ist es nicht sinnvoll zu prüfen, ob der String einen passenden regulären Ausdruck hat?
Buhbang
0

Dies ist mein Benchmark-Ergebnis Benchmark-Ergebnisse

Test 4,267,740 ops / s ± 1,32% (60 Läufe abgetastet)

Exec 3.649.719 Ops / Sek. ± 2,51% (60 Läufe abgetastet)

Übereinstimmung 3.623.125 ops / s ± 1,85% (62 Läufe abgetastet)

Index von 6.230.325 ops / s ± 0,95% (62 Läufe abgetastet)

Die Testmethode ist schneller als die Match-Methode, aber die schnellste Methode ist der indexOf

Ramil Shavaleev
quelle
indexOf funktioniert nicht mit regulären Ausdrücken, die so irrelevant sind.
Gdoron unterstützt Monica