regex.test VS string.match, aby dowiedzieć się, czy łańcuch pasuje do wyrażenia regularnego

287

Wiele razy używam matchfunkcji string, aby sprawdzić, czy łańcuch pasuje do wyrażenia regularnego.

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

Czy jest jakaś różnica między tym:

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

Wydają się dawać ten sam wynik?

gdoron wspiera Monikę
źródło
4
są to najlepsze testy, które znajdziesz jsperf.com/regexp-test-vs-match-m5
ajax333221
@ ajax333221. Dzięki za jsperf, ale nie jestem pewien, czy to jest dobre. Dopasowanie wyrażenia regularnego przy użyciu grupy dopasowań, które nie jest potrzebne, gdy szukamy wartości logicznej.
gdoron wspiera Monikę

Odpowiedzi:

440

Podstawowe użycie

Najpierw zobaczmy, co robi każda funkcja:

regexObject . test ( ciąg )

Wykonuje wyszukiwanie dopasowania między wyrażeniem regularnym a określonym ciągiem. Zwraca true lub false .

ciąg . dopasowanie ( RegExp )

Służy do wyszukiwania dopasowań podczas dopasowywania łańcucha do wyrażenia regularnego. Zwraca tablicę z dopasowaniami lub nulljeśli nie ma żadnych.

Ponieważ nullocenia false,

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

Występ

Czy jest jakaś różnica w wydajności?

Tak . Znalazłem tę krótką notatkę na stronie MDN :

Jeśli chcesz wiedzieć, czy ciąg pasuje do wyrażenia regularnego regexp, użyj regexp.test (string).

Czy różnica jest znacząca?

Odpowiedź jeszcze raz brzmi TAK ! To zestawienie jsPerf pokazuje, że różnica wynosi ~ 30% - ~ 60% w zależności od przeglądarki:

test vs mecz |  Test wydajności

Wniosek

Użyj, .testjeśli chcesz szybciej sprawdzić wartość logiczną. Służy .matchdo pobierania wszystkich dopasowań podczas korzystania z gflagi globalnej.

gdoron wspiera Monikę
źródło
5
Nie jest to zbyt zaskoczone, ponieważ funkcja stringu musi odwracać rzeczy, a następnie utworzyć tablicę, jeśli istnieje dopasowanie. Wygląda na to, że będę nadal używać .test(). :)
22
Moje dwa centy: wydajność jest przereklamowana. Każda z opcji może wykonać ~ 15 000 operacji w migotaniu monitora, więc jeśli nie robisz hurtowych wyrażeń regularnych po stronie klienta, szybkość nie jest istotna. Oczywiście „test” jest logicznie poprawną funkcją, jeśli szukasz wyniku logicznego. Dzięki za Q / A BTW.
David Gilbertson,
2
Co ciekawe, test jest o 41% wolniejszy niż mecz dla mnie przy użyciu powyższego testu jsPerf (Chrome 41, OSX).
Benjie,
1
@AlexShilman indexOf jest szybszy (ale niewiele) niż test zgodnie z tym stackoverflow.com/questions/183496/… (można by oczekiwać, że będzie szybszy).
podperson
1
Jedna rzecz, która może Cię ugryźć (ostatnio ugryzł mój zespół): Jeśli użyjesz flagi „g” na Regeksie i utworzysz nową instancję (tj. Poprzez nową RegExp (<regex_str>, „g”)) i użyjesz jej ponownie instancja, uruchomienie „testu” jest stanowe, tzn. zwróci różne wyniki przy wielokrotnym uruchomieniu. Szczegółowe informacje można znaleźć na stronie developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ ...
davertron
118

Nie zapomnij wziąć pod uwagę flagi globalnej w wyrażeniu regularnym:

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

Wynika to z faktu, że Regexp śledzi lastIndex po znalezieniu nowego dopasowania.

gtournie
źródło
21
Właśnie waliłem głową, widząc, że mój regex.test () losowo rejestruje „prawda”, następnie „fałsz”, a następnie „prawda” ... dzięki!
adriendenat
7
Myślę, że to lepsza odpowiedź. Wyjaśnia, że ​​nie dają tego samego wyniku i że reg.test () ma niebezpieczną pułapkę. Dla mnie to sprawia, że ​​string.match () jest oczywistym wyborem. Wydajność nigdy nie była dla mnie problemem.
James
2
To jest ważne! Wariuje próbuje dowiedzieć się, dlaczego każdy inny wynik brakowało ... dla odniesienia ktokolwiek inny, że znaleziska to: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
Dan
2
Jeśli jesteś tak zdezorientowany jak ja, zobacz stackoverflow.com/q/1520800/3714913 . Istnieje również String.prototype.search () , który zwraca indeks, ale nie ma tego problemu, o ile wiem.
Nateowami,
3
Ciekawe, po co jest globalna flaga .test() ? nie ma sensu .test()sprawdzać, czy ciąg ma pasujące wyrażenie regularne?
buhbang
0

To są moje wyniki testów wyniki testu porównawczego

test 4,267,740 operacji / sek ± 1,32% (próbka 60 prób)

exec 3,649,719 operacji / s ± 2,51% (próbka 60 przebiegów)

dopasuj 3,623,125 operacji / sek ± 1,85% (próbka 62 przebiegów)

indeks 6,230,325 operacji / sek ± 0,95% (próbkowanie 62 przebiegów)

metoda testowa jest szybsza niż metoda dopasowania, ale najszybszą metodą jest indexOf

Ramil Shavaleev
źródło
Funkcja indexOf nie działa z wyrażeniami regularnymi, więc jest nieistotna.
gdoron wspiera Monikę