regex.test VS string.match per sapere se una stringa corrisponde a un'espressione regolare


287

Molte volte sto usando la matchfunzione stringa per sapere se una stringa corrisponde a un'espressione regolare.

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

C'è qualche differenza tra questo:

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

Sembrano dare lo stesso risultato?


4
questi sono i migliori test che troverai jsperf.com/regexp-test-vs-match-m5
ajax333221

@ ajax333221. Grazie per il jsperf, ma non sono sicuro che sia buono. La regex corrisponde usando un gruppo di corrispondenza, che non è necessario quando si guarda un valore booleano.
gdoron sostiene Monica l'

Risposte:


440

Utilizzo di base

Innanzitutto, vediamo cosa fa ogni funzione:

regexObject . test ( stringa )

Esegue la ricerca di una corrispondenza tra un'espressione regolare e una stringa specificata. Restituisce vero o falso .

stringa . match ( RegExp )

Utilizzato per recuperare le corrispondenze quando si confronta una stringa con un'espressione regolare. Restituisce un array con le corrispondenze o nullse non ce ne sono.

Poiché nullvaluta false,

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

Prestazione

C'è qualche differenza riguardo alle prestazioni?

. Ho trovato questa breve nota nel sito MDN :

Se devi sapere se una stringa corrisponde a un'espressione regolare regexp, usa regexp.test (stringa).

La differenza è significativa?

La risposta è di nuovo ! Questo jsPerf che ho messo insieme mostra che la differenza è ~ 30% - ~ 60% a seconda del browser:

test vs match |  Test della prestazione

Conclusione

Utilizzare .testse si desidera un controllo booleano più veloce. Utilizzare .matchper recuperare tutte le partite quando si utilizza la gbandiera globale.


5
Non troppo sorpreso poiché la funzione stringa deve capovolgere le cose e quindi creare l'array se c'è una corrispondenza. Sembra che continuerò a usare .test(). :)

22
I miei due centesimi: le prestazioni sono sopravvalutate. Entrambe le opzioni possono eseguire circa 15.000 operazioni con lo sfarfallio di un monitor, quindi a meno che non si esegua regex in blocco sul lato client, la velocità non è rilevante. Naturalmente 'test' è logicamente la funzione corretta se un risultato booleano è ciò che stai cercando. Grazie per il Q / A BTW.
David Gilbertson,

2
È interessante notare che il test è del 41% più lento rispetto a quello per me utilizzando il test jsPerf sopra (Chrome 41, OSX).
Benjie,

1
@AlexShilman indexOf è più veloce (ma non molto) del test secondo questo stackoverflow.com/questions/183496/… (ti aspetteresti che sia più veloce).
podperson,

1
Una cosa che potrebbe morderti qui (mi ha morso di recente il mio team): se usi il flag 'g' sul tuo Regex e crei una nuova istanza (cioè tramite il nuovo RegExp (<regex_str>, 'g')) e riutilizzi quello ad esempio, l'esecuzione di "test" è stateful, ovvero restituirà risultati diversi se eseguito più volte. Vedi developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… per i dettagli.
Davertron,

118

Non dimenticare di prendere in considerazione la bandiera globale nel tuo regexp:

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

Questo perché Regexp tiene traccia di lastIndex quando viene trovata una nuova corrispondenza.


21
Stavo solo sbattendo la testa visto che il mio regex.test () stava registrando casualmente "vero" poi "falso" poi "vero" ... grazie!
adriendenat,

7
Penso che questa sia la risposta migliore. Spiega che non danno lo stesso risultato e che reg.test () ha una trappola pericolosa. Per me questo rende string.match () la scelta chiara. Le prestazioni non sono mai state un problema per me.
James,

2
Questo è importante! Impazzendo cercando di capire perché mancava ogni altro risultato ... come riferimento per chiunque altro lo trovi: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Dan

2
Se sei confuso quanto me, vedi stackoverflow.com/q/1520800/3714913 . C'è anche String.prototype.search () , che restituisce un indice ma non ha questo problema per quanto posso dire.
Nateowami,

3
Solo curioso, a che serve avere una bandiera globale .test()? non è il punto di .test()verificare se la stringa ha una regexp corrispondente?
Buhbang,

0

Questo è il mio risultato di riferimento risultati di riferimento

test 4.267.740 ops / sec ± 1,32% (60 serie campionate)

exec 3.649.719 ops / sec ± 2,51% (60 serie campionate)

corrispondenza 3,623,125 op / sec ± 1,85% (62 serie campionate)

indice di 6.230.325 op / sec ± 0,95% (62 serie campionate)

il metodo di test è più veloce del metodo di corrispondenza, ma il metodo più veloce è indexOf


indexOf non funziona con regex così irrilevanti.
gdoron supporta Monica il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.