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?


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.


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.


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


Funkcja indexOf nie działa z wyrażeniami regularnymi, więc jest nieistotna.
gdoron wspiera Monikę
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.