DEV Community

Erandir Junior
Erandir Junior

Posted on • Edited on

Validando dados com Regex

Expressões Regulares, em inglês Regular Expression (Regex), nada mais são do que padrões para validação ou captura de informações. Em outras palavras, é um recurso muito poderoso e útil para manipular dados.

Estudo de caso simples

Nada melhor do que aprender algo na prática, não é mesmo? Pensando nisso, tive a ideia de fazermos uma validação de e-mails, assim conseguiremos pôr em prática alguns recursos que uma regex oferece.

Os códigos abaixo serão feitos com JavaScript, pois acho que vai ser mais simples de explicar e de praticar, vocês podem utilizar o console do navegador para executar os códigos.

// Primeiramente vamos definir uma variável que contenha um e-mail qualquer
let email = 'erandirjunior@email.com';
Enter fullscreen mode Exit fullscreen mode

Agora com a ajuda do método match, iremos criar nossa primeira expressão, e validar se o dado informado atende o nosso padrão:

/*
Em JS podemos definir uma expressão regular de forma literal ou pelo uso do objeto RegExp.
Nos exemplos utilizarei a forma literal, bastando definir a expressão por meio do //.

O código abaixo vai retornar um array contendo algumas informações,
caso nossa verificação falhasse, receberíamos null como retorno
*/
email.match(/erandirjunior@email.com/);
Enter fullscreen mode Exit fullscreen mode

Para primeira validação, não temos nada complicado, passamos basicamente o mesmo valor contido na nossa variável email. A partir de agora vamos deixar nossa expressão mais genérica e ver o quão poderoso e útil pode ser uma regex.

Um recurso interessante que podemos utilizar é o metacaractere \w, ele serve para representar uma letra, número e o underline, vejam abaixo:

email.match(/\w\w\w\w\w\w\w\w\w\w\w\w\w@email.com/);
// Obtemos o mesmo resultado que o código anterior
Enter fullscreen mode Exit fullscreen mode

Só reforçando, o metacaractere \w substitui letras de a-z, A-Z e números de 0-9 e o caractere _.

O exemplo acima não tá legal pois estamos sendo repetitivos, vamos melhorar nosso código informando que determinado caractere pode se repetir uma quantidade específica de vezes:

email.match(/\w{13}@email.com/);
Enter fullscreen mode Exit fullscreen mode

Acima informamos que um caractere - dentro da regra explicada anteriormente - deve aparecer no mínimo e no máximo 13 vezes.

Nosso padrão até então aceita letras, números e _ no início do nosso e-mail, vamos informar que também podemos aceitar ., para isso vamos fazer uso de um agregador de caracteres, vejam:

email.match(/[a-zA-Z0-9._]{13}@email.com/);
Enter fullscreen mode Exit fullscreen mode

Podemos agrupar caracteres por meio do [], e dentro colocamos tudo o que é aceito. Em nosso caso, informamos que é aceito exclusivamente letras de a até z minúsculas, letras de A até Z maiúsculas, números, o ponto e o underline. Outro ponto a se destacar, é que a ordem do caracteres não importa, então poderíamos ter um e-mail iniciando com . ou _ por exemplo.

Continuando, nossa validação passou, porém, se passarmos um e-mail diferente, com caracteres a menos ou a mais, teremos comportamentos estranhos, executem o código abaixo e notem o retorno:

'erandir.junior@email.com'.match(/[a-zA-Z0-9._]{13}@email.com/);
// Verifiquem o conteúdo do retorno e vejam que foi ignorado a primeira letra
Enter fullscreen mode Exit fullscreen mode

Para corrigir isso, podemos fazer de duas formas, a primeira é informar uma quantidade mínima e deixar a máxima em aberto:

// O valor mínimo aceito é de 1 caractere e não temos valor máximo, mas podemos definir.
email.match(/[a-zA-Z0-9._]{1,}@email.com/);

'erandir.junior@email.com'.match(/[a-zA-Z0-9._]{1,}@email.com/);
Enter fullscreen mode Exit fullscreen mode

Já a segunda forma de corrigir é substituir o quantificador {}, por +:

email.match(/[a-zA-Z0-9._]+@email.com/);

'erandir.junior@email.com'.match(/[a-zA-Z0-9._]+@email.com/);
Enter fullscreen mode Exit fullscreen mode

A grande diferença entre eles, é que o quantificador + informa que um caractere ou mais deve existir, já no quantificador {}, podemos definir uma quantidade fixa, apenas a mínima ou a quantidade mínima e máxima.

Até aqui estamos indo bem, agora vamos trabalhar em cima do host do e-mail, aquela parte depois do @:

email.match(/[a-zA-Z0-9._]+@[a-zA-Z0-9]+.com/);
Enter fullscreen mode Exit fullscreen mode

Existem e-mails que contém o identificador do país, por exemplo e-mails que terminam em .com.br. No código abaixo, vamos informar que o .algumacoisa, após o .com, é completamente opcional:

email.match(/[a-zA-Z0-9._]+@[a-zA-Z0-9._]+.com(?:.[a-z]+)?/);
Enter fullscreen mode Exit fullscreen mode

Explicando de forma mais detalhada a modificação realizada:

  • Primeiramente envolvemos um código em um grupo de captura por meio de (), veremos isso mais detalhadamente em outro artigo;
  • Em segundo lugar, informamos que não queremos capturar o grupo, isso por meio do ?:;
  • Depois informamos que os caracteres aceitos são o . e obrigatoriamente depois um conjunto de caracteres, neste caso, de a até z, sendo no mínimo 1 caractere;
  • E por último, Utilizando o ?, informamos que um caractere, grupo, etc, é opcional. No nosso caso, todo o grupo é opcional.

Espero que tenham entendido até aqui, mesmo assim, vai ficar muito mais claro com outros exemplos.

Até aqui passamos de uma validação fixa para uma dinâmica. Agora vamos adicionar mais uma regra, particularmente quando me cadastro em um site, costumo adicionar algo no e-mail que me permita identificar esse e-mail posteriormente como único, em outras palavras, posso me cadastrar assim: erandirjunior+teste@email.com. Onde o +teste, por exemplo, poderia ser o nome do site, ou algo do tipo. Vamos aplicar essa regra em nosso código:

email.match(/[a-zA-Z0-9._]+(?:\+[a-zA-Z0-9._]+)?@[a-zA-Z0-9._]+.com(?:.[a-z]+)?/);

'erandir.junior@email.com'.match(/[a-zA-Z0-9._]+(?:\+[a-zA-Z0-9._]+)?@[a-zA-Z0-9._]+.com(?:.[a-z]+)?/);

'erandir.junior@email.com.br'.match(/[a-zA-Z0-9._]+(?:\+[a-zA-Z0-9._]+)?@[a-zA-Z0-9._]+.com(?:.[a-z]+)?/);

'erandir.junior+teste@email.com.br'.match(/[a-zA-Z0-9._]+(?:\+[a-zA-Z0-9._]+)?@[a-zA-Z0-9._]+.com(?:.[a-z]+)?/);
Enter fullscreen mode Exit fullscreen mode

O detalhe dos códigos acima ficam por conta da necessidade de escapar o caractere +, para que não seja entendido como um quantificador e sim como um caractere comum.

Calma que não paramos por aqui, quero explicar mais uma coisa, digamos que a string que contenha o e-mail venha com um espaço no início ou fim. Isso pode ser um problema, então vamos informar que o dado que vier tem que obrigatoriamente iniciar e terminar com nossa validação, para isso basta adicionar os caracteres ^ no início e $ no final:

email.match(/^[a-zA-Z0-9._]+(?:\+[a-zA-Z0-9._]+)?@[a-zA-Z0-9._]+.com(?:.[a-z]+)?$/);

// Isso não funciona
' erandir.junior@email.com'.match(/^[a-zA-Z0-9._]+(?:\+[a-zA-Z0-9._]+)?@[a-zA-Z0-9._]+.com(?:.[a-z]+)?$/);

// Isso não funciona
'erandir.junior@email.com.br '.match(/^[a-zA-Z0-9._]+(?:\+[a-zA-Z0-9._]+)?@[a-zA-Z0-9._]+.com(?:.[a-z]+)?$/);

// Funciona
'erandir.junior+teste@email.com.br'.match(/^[a-zA-Z0-9._]+(?:\+[a-zA-Z0-9._]+)?@[a-zA-Z0-9._]+.com(?:.[a-z]+)?$/);
Enter fullscreen mode Exit fullscreen mode

Gostaria de lembrar que definimos uma regra onde aceitamos letras, números, ponto e undeline na primeira parte de um e-mail, porém, isso não impede de termos . ou _ como primeiro caractere, então vamos definir uma regra, na qual o primeiro caractere só pode ser letra, e o caractere seguinte pode ser qualquer outro.

email.match(/^[^0-9._][a-zA-Z0-9._]+(?:\+[a-zA-Z0-9._]+)?@[a-zA-Z0-9._]+.com(?:.[a-z]+)?$/);
Enter fullscreen mode Exit fullscreen mode

Pode parecer confuso, e realmente é, não vou mentir pra vocês, mas com calma vocês vão entender: lembrando que dentro de [] nós definimos o que é aceito, e que ^ no começo de uma regex, informa que a string a ser manipulada deve iniciar exatamente com as regras definidas no padrão, porém, quando utilizamos o ^ dentro do agrupador [], dizemos que tudo definido dentro de [], não é aceito. Viram como não é complicado?

Um último ponto que gostaria de falar, é sobre o host de um e-mail, digamos que agora só vamos validar e-mails com host xpto ou ywz, então podemos alterar um pouco a nossa regra, veja abaixo:

// Aqui vai falhar pois nosso e-mail tem o host diferente do aceito
email.match(/^[^0-9._][a-zA-Z0-9._]+(?:\+[a-zA-Z0-9._]+)?@(?:xpto|xwz).com(?:.[a-z]+)?$/);

// Aqui vai funcionar pois nosso host é um dos aceitos
'erandir.junior@xpto.com.br'.match(/^[^0-9._][a-zA-Z0-9._]+(?:\+[a-zA-Z0-9._]+)?@(?:xpto|xwz).com(?:.[a-z]+)?$/);
Enter fullscreen mode Exit fullscreen mode

Dica

Um site muito útil e que utilizo sempre que vou definir uma regex, é o https://regex101.com/, nele eu consigo testar regex, ver os recursos disponíveis e ainda exportar o código para a linguagem de programação que utilizo, vejam a imagem a seguir para maiores detalhes:
Image description

Finalizando

Neste artigo pude mostrar alguns recursos bem úteis que uma expressão pode oferecer, acredito que apesar de não vermos tudo que uma regex oferece, com os recursos mostrados, pode-se fazer a validação de outras coisas, bastando adaptar os exemplos mostrados acima. Nos próximos artigos veremos outras funcionalidades, vejo você por lá, até mais.

Top comments (1)

Collapse
 
mentorduncan profile image
mentorduncan

Rapaz... muito bem escrito!
Parabéns e obrigado!