regex.test VS string.match para saber si una cadena coincide con una expresión regular

287

Muchas veces estoy usando la matchfunción de cadena para saber si una cadena coincide con una expresión regular.

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

¿Hay alguna diferencia entre esto?

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

¿Parecen dar el mismo resultado?

gdoron está apoyando a Monica
fuente
44
Estas son las mejores pruebas que encontrará jsperf.com/regexp-test-vs-match-m5
ajax333221
@ ajax333221. Gracias por el jsperf, pero no estoy seguro de que sea bueno. La coincidencia de expresiones regulares utiliza un grupo de coincidencias, que no es necesario cuando se busca un valor booleano.
Gdoron está apoyando a Monica el

Respuestas:

440

Uso básico

Primero, veamos qué hace cada función:

regexObject . prueba ( cadena )

Ejecuta la búsqueda de una coincidencia entre una expresión regular y una cadena especificada. Devuelve verdadero o falso .

cadena . partido ( RegExp )

Se usa para recuperar las coincidencias al hacer coincidir una cadena con una expresión regular. Devuelve una matriz con las coincidencias o nullsi no hay ninguna.

Como se nullevalúa como false,

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

Actuación

¿Hay alguna diferencia con respecto al rendimiento?

. Encontré esta breve nota en el sitio de MDN :

Si necesita saber si una cadena coincide con una expresión regular regexp, use regexp.test (string).

¿Es significativa la diferencia?

¡La respuesta una vez más es ! Este jsPerf que reuní muestra que la diferencia es ~ 30% - ~ 60% dependiendo del navegador:

prueba vs partido |  Prueba de rendimiento

Conclusión

Úselo .testsi desea un cheque booleano más rápido. Use .matchpara recuperar todas las coincidencias cuando use la gbandera global.

gdoron está apoyando a Monica
fuente
55
No está demasiado sorprendido ya que la función de cadena necesita cambiar las cosas y luego crear la matriz si hay una coincidencia. Parece que seguiré usando .test(). :)
22
Mis dos centavos: el rendimiento está sobrevalorado. Cualquiera de las opciones puede realizar ~ 15,000 operaciones en el parpadeo de un monitor, por lo que a menos que esté haciendo expresiones regulares masivas del lado del cliente, la velocidad no es relevante. Por supuesto, 'prueba' es lógicamente la función correcta si lo que buscas es un resultado booleano. Gracias por el Q / A BTW.
David Gilbertson el
2
Curiosamente, la prueba es un 41% más lenta que la coincidencia para mí usando la prueba jsPerf anterior (Chrome 41, OSX).
Benjie
1
@AlexShilman indexOf es más rápido (pero no mucho) que la prueba de acuerdo con este stackoverflow.com/questions/183496/… (es de esperar que sea más rápido).
podperson
1
Una cosa que podría morderte aquí (mordió a mi equipo recientemente): si usas la bandera 'g' en tu Regex y creas una nueva instancia (es decir, a través de un nuevo RegExp (<regex_str>, 'g')) y reutilizas eso Por ejemplo, ejecutar "test" tiene estado, es decir, devolverá resultados diferentes cuando se ejecute varias veces. Consulte developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… para más detalles.
davertron
118

No olvides tener en cuenta la bandera global en tu expresión regular:

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

Esto se debe a que Regexp realiza un seguimiento del último índice cuando se encuentra una nueva coincidencia.

gtournie
fuente
21
Estaba golpeando la cabeza al ver que mi regex.test () registraba aleatoriamente "verdadero" y luego "falso" y luego "verdadero" ... ¡gracias!
adriendenat
77
Creo que esta es la mejor respuesta. Explica que no dan el mismo resultado y que reg.test () tiene un peligro peligroso. Para mí, esto hace que string.match () sea la opción clara. El rendimiento nunca ha sido un problema para mí.
James
2
¡Esto es importante! Volviéndose loco tratando de descubrir por qué faltaban todos los demás resultados ... para referencia de cualquier otra persona que encuentre esto: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Dan
2
Si está tan confundido como yo, consulte stackoverflow.com/q/1520800/3714913 . También hay String.prototype.search () , que devuelve un índice pero no tiene este problema por lo que puedo decir.
Nateowami
3
Solo por curiosidad, ¿para qué sirve tener una bandera global .test()? ¿no es el punto de .test()verificar si la cadena tiene una expresión regular coincidente?
buhbang
0

Este es mi resultado de referencia resultados de referencia

prueba 4,267,740 operaciones / seg. ± 1.32% (60 corridas muestreadas)

ejecutivo 3,649,719 operaciones / seg. ± 2.51% (60 corridas muestreadas)

partido 3,623,125 operaciones / seg ± 1.85% (62 carreras muestreadas)

índice de 6.230.325 operaciones / seg. ± 0.95% (62 ejecuciones muestreadas)

El método de prueba es más rápido que el método de coincidencia, pero el método más rápido es el indexOf

Ramil Shavaleev
fuente
indexOf no funciona con expresiones regulares tan irrelevante.
Gdoron está apoyando a Mónica el