Regex em Java: Validando dados com expressões regulares

Regex em Java: Validando dados com expressões regulares

No meu sistema de cadastro de alunos eu recebo um aluno com os seguintes atributos:


public class Aluno {

private String nome;
private String sobrenome;
private String telefone;

//métodos

}

Ao imprimir os dados de um aluno:

Banner da Escola de Programação: Matricula-se na escola de Programação. Junte-se a uma comunidade de mais de 500 mil estudantes. Na Alura você tem acesso a todos os cursos em uma única assinatura; tem novos lançamentos a cada semana; desafios práticos. Clique e saiba mais!
 Nome: Alex2016 Sobrenome: 12Felipe Telefone: 11992232121455

Alex2016? 12Felipe? E esse telefone bizarro? Esse aluno contém informações que não fazem sentido...

Como posso fazer para impedir que esses tipos de dados sejam inseridos no meu sistema?

Vamos tentar validar esses dados criando um método que valida o aluno:


public boolean valida(Aluno aluno) {

//implementação

}

Vamos começar pelo nome do aluno. Não queremos que tenha números nem no começo e nem no final do nome! Como podemos fazer isso?

Vamos extrair tanto o primeiro caracter quanto o último por meio do método charAt() da classe String:


public boolean valida(Aluno aluno) {

String nome = aluno.getNome(); 
char primeiraLetra = nome.charAt(0);
char ultimaLetra = nome.charAt(nome.length() - 1)

}

Para verificar se um caracter é uma letra, podemos usar o método estático isAlphabetic() da classe <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/Character.html">Character</a>:


public boolean valida(Aluno aluno) {

String nome = aluno.getNome();

if (Character.isAlphabetic((nome.charAt(0))) && Character.isAlphabetic((nome.charAt(nome.length() - 1)))) { 
    return true;
    }

return false; }

Implementamos nossa primeira validação! Vamos agora adicionar um sysout dentro de um if para testarmos:


if (valida(aluno)) { 
    System.out.println("aluno " + aluno.getNome() + " é válido");
     } else { 
         System.out.println("aluno " + aluno.getNome() + " é inválido");
}

Vamos testar um nome que começa com um número, no caso "1Alex":

 aluno 1Alex é inválido

Ótimo! Funcionou como o esperado. Mas, e se o número estiver no final? Por exemplo, o que foi apresentado no começo: "Alex2016". Vamos ver o resultado:

 aluno Alex2016 é inválido

Aparentemente tudo está funcionando conforme o esperado! Agora, e se um número estivesse no meio do nome? Por exemplo "A1ex":

 aluno A1ex é válido

Eita! Não pensamos nesse caso! Como podemos fazer com que o nome do aluno não tenha nenhum número? Precisaremos "varrer" toda a nossa String, caracter por caracter e verificar se é válido:


public boolean valida(Aluno aluno) {

String nome = aluno.getNome();

for (int i = 0; i < nome.length(); i++) { 
    if (!Character.isAlphabetic((nome.charAt(i)))) { 
        return false; } }

return true; }

Se testarmos novamente com o nome "A1ex":

 aluno A1ex é inválido

Ótimo! Agora o nome do meu aluno está sendo validado conforme o esperado! E se recebermos um aluno que tenha inserido o nome com apenas uma letra? Como "A" por exemplo... o que aconteceria?

 aluno A é válido

Hmmm, mas com certeza para o meu sistema não faz sentido um aluno com o nome de apenas 1 letra...então adicionaremos mais uma condição no nosso validador:


public boolean valida(Aluno aluno) {

String nome = aluno.getNome();

if(nome.length() > 2){ return false; }

//restante do código

}

Se testarmos agora:

 aluno A é inválido

A nossa validação por enquanto está funcionando, mas olha o tamanho que ficou o método:


public boolean valida(Aluno aluno) {

String nome = aluno.getNome();

if(nome.length() > 2){ return false; }

for (int i = 0; i > nome.length(); i++) { 
    if (!Character.isAlphabetic((nome.charAt(i)))) { 
        return false; } }

return true; }

À primeira vista conseguimos entender o que está sendo feito? Provavelmente não.

Note também que a cada validação que precisamos fazer são mais ifs que precisamos adicionar. Será que existe outra forma mais simples para validarmos esses dados? A resposta é sim!

Podemos utilizar expressões regulares por meio do método matches() da classe String. Vamos definir nossa expressão regular para validar o nome do aluno:


public boolean valida(Aluno aluno) {

String nome = aluno.getNome();

return nome.matches("[a-z]");

}

Certo, essa expressão regular significa que esperamos apenas 1 única letra do alfabeto. Mas o que queremos é que tenha pelo menos 2, certo? Simples! Basta adicionar chaves ({}) e informar a quantidade de repetições que você deseja:


public boolean valida(Aluno aluno) {

String nome = aluno.getNome();

return nome.matches("[a-z]{2}");

}

Nesse exemplo estamos informando que queremos apenas 2 repetições, ou seja, a quantidade não pode ser maior ou menor e sim igual a 2 letras! Com certeza não é isso que queremos! E agora? Como podemos dizer que queremos pelo menos 2 letras?

Quando utilizamos as chaves podemos passar 2 parâmetros: o primeiro significa a quantidade mínima e o segundo a quantidade máxima. Ou seja, se adicionarmos apenas uma ",":


public boolean valida(Aluno aluno) {

String nome = aluno.getNome();

return nome.matches("[a-z]{2,}");

}

Nesse instante estamos dizendo que esperamos pelo menos 2 letras e a quantidade máxima não tem limite!

Se testarmos o nome "Alex":

 aluno Alex é inválido

O que aconteceu? Não era pra ser válido? A nossa expressão regular diz que espera pelo menos 2 letras, porém letras minúsculas! Agora, como podemos fazer com que a nossa expressão regular espere uma letra maiúscula no começo? Da mesma forma que pra letras minúsculas usamos [a-z] podemos usar [A-Z] para letras maiúsculas:


public boolean valida(Aluno aluno) {

String nome = aluno.getNome();

return nome.matches("[A-Z][a-z]{1,}");

}

Agora a nossa expressão regular está esperando uma String com a primeira letra maiúscula e por isso precisamos apenas garantir que terá pelo menos 1 letra minúscula depois! Se tentarmos rodar novamente:

 aluno Alex é válido

E se tentarmos com aqueles nomes inválidos? Por exemplo: "A1ex", "1Alex" e o "Alex2016"? Vejamos o resultado:

 aluno A1ex é inválido
 aluno 1Alex é inválido
 aluno Alex2016 é inválido

Excelente! Tudo funciona como o esperado e de uma forma mais clara e de fácil manutenção! Se um dia precisarmos modificar nossa validação, basta adaptar a nossa expressão regular para a nova regra de negócio :)

O que achou da expressão regular? Que tal um desafio? Faça a definição de uma expressão regular para validar um telefone que aceite apenas telefones nesses 2 formatos: (11) 1111-1111 ou (11) 11111-1111. Comente o seu resultado!

E aí, curtiu expressões regulares? Que tal aprender mais sobre o assunto? Na Alura, o curso de expressão regulares aborda mais detalhes sobre esse recurso poderoso que facilita, e muito, a vida do programador na hora de realizar diversas validações!

Alex Felipe
Alex Felipe

Alex é instrutor e desenvolvedor e possui experiência em Java, Kotlin, Android. Atualmente cria conteúdo no canal https://www.youtube.com/@AlexFelipeDev.

Veja outros artigos sobre Programação