regex.test VS string.match para saber se uma string corresponde a uma expressão regular

287

Muitas vezes, estou usando a matchfunção string para saber se uma string corresponde a uma expressão regular.

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

Existe alguma diferença entre isso:

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

Eles parecem dar o mesmo resultado?

gdoron está apoiando Monica
fonte
4
estes são os melhores testes que você vai encontrar jsperf.com/regexp-test-vs-match-m5
ajax333221
@ ajax333221. Obrigado pelo jsperf, mas não tenho certeza de que seja bom. A regex corresponde usando um grupo de correspondência, o que não é necessário ao procurar um valor booleano.
gdoron está apoiando Monica

Respostas:

440

Uso básico

Primeiro, vamos ver o que cada função faz:

regexObject . teste ( String )

Executa a pesquisa de uma correspondência entre uma expressão regular e uma sequência especificada. Retorna verdadeiro ou falso .

string . match ( RegExp )

Usado para recuperar as correspondências ao corresponder uma sequência a uma expressão regular. Retorna uma matriz com as correspondências ou nullse não houver nenhuma.

Como nullavalia como false,

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

atuação

Existe alguma diferença em relação ao desempenho?

Sim . Encontrei esta breve nota no site MDN :

Se você precisar saber se uma string corresponde a uma expressão regular regexp, use regexp.test (string).

A diferença é significativa?

A resposta mais uma vez é SIM ! Este jsPerf que montei mostra que a diferença é de ~ 30% a ~ 60%, dependendo do navegador:

teste vs partida |  Teste de performance

Conclusão

Use .testse você quiser uma verificação booleana mais rápida. Use .matchpara recuperar todas as correspondências ao usar a gbandeira global.

gdoron está apoiando Monica
fonte
5
Não é de surpreender, pois a função string precisa inverter as coisas e criar a matriz, se houver uma correspondência. Parece que vou continuar usando .test(). :)
22
Meus dois centavos: o desempenho é superestimado. Qualquer uma das opções pode realizar ~ 15.000 operações no piscar de um monitor; portanto, a menos que você esteja fazendo regex em massa no lado do cliente, a velocidade não é relevante. É claro que 'test' é logicamente a função correta se você procura um resultado booleano. Obrigado pelo Q / A BTW.
precisa
2
Curiosamente, o teste é 41% mais lento do que o indicado para mim usando o teste jsPerf acima (Chrome 41, OSX).
21415 Benjie
1
@AlexShilman indexOf é mais rápido (mas não muito) do que o teste de acordo com este stackoverflow.com/questions/183496/… (você esperaria que fosse mais rápido).
podperson
1
Uma coisa que pode incomodá-lo aqui (mordeu minha equipe recentemente): se você usar o sinalizador 'g' no seu Regex e criar uma nova instância (por exemplo, através do novo RegExp (<regex_str>, 'g')) e você reutilizar esse Por exemplo, a execução de "teste" é estável, ou seja, retornará resultados diferentes quando executada várias vezes. Veja developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… para obter detalhes.
Davertron 19/07/19
118

Não se esqueça de levar em consideração a bandeira global no seu regexp:

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

Isso ocorre porque o Regexp monitora o lastIndex quando uma nova correspondência é encontrada.

gtournie
fonte
21
Eu estava batendo cabeça, vendo que meu regex.test () estava registrando aleatoriamente "true", depois "false" e depois "true" ... obrigado!
adriendenat
7
Eu acho que essa é a melhor resposta. Explica que eles não dão o mesmo resultado e que reg.test () tem uma armadilha perigosa. Para mim, isso torna string.match () a escolha clara. O desempenho nunca foi um problema para mim.
James
2
Isso é importante! Enlouquecendo tentando descobrir por que todos os outros resultados estavam faltando ... para referência de qualquer outra pessoa que encontre isso: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Dan
2
Se você está tão confuso quanto eu, consulte stackoverflow.com/q/1520800/3714913 . Há também String.prototype.search () , que retorna um índice, mas não tem esse problema até onde eu sei.
Nateowami 19/03
3
Apenas curioso, para que serve uma bandeira global .test()? não é o ponto de .test()verificar se a string tem um regexp correspondente?
buhbang
0

Este é o meu resultado de benchmark resultados de benchmark

teste 4.267.740 ops / s ± 1,32% (60 execuções amostradas)

exec 3.649.719 ops / s ± 2,51% (60 execuções amostradas)

corresponder a 3.623.125 ops / s ± 1,85% (62 execuções amostradas)

índiceDe 6.230.325 ops / s ± 0,95% (62 execuções amostradas)

O método de teste é mais rápido que o método de correspondência, mas o método mais rápido é o indexOf

Ramil Shavaleev
fonte
indexOf não funciona com expressões regulares tão irrelevantes.
gdoron apoia Monica em