Verificar se é letra ou número no Java

(Last Updated On: 5 de Janeiro de 2018)

Estamos desenvolvendo um sistema web para venda de automóveis usados. Uma das informações necessárias para cadastrar um automóvel no sistema é o número da placa do veículo.

Precisamos criar uma funcionalidade que valide as placas do carro, para que os usuários não saiam enviando para o servidor dados incorretos. Uma placa de carro válida por exemplo seria “FXZ-9846” e uma inválida “FX4-Z432”. Para fazer tal validação precisamos seguir algumas regras, sendo elas:

  • Número de caracteres tem que ser igual a 7
  • Os 3 primeiros caracteres são letras
  • Os 4 últimos caracteres são dígitos

Validando a placa

Primeiro, criaremos um método que recebe uma placa e devolve um boolean para fazer a verificação do que foi inserido.


public static boolean validaPlaca(String placa){        
}

Podemos colocar uma variável do tipo boolean que será nosso retorno após as validações:


public static boolean validaPlaca(String placa){        
   boolean valido = true;
   //aqui ficarão nossas validações
   return valido;
}

A primeira validação que vamos fazer será referente ao tamanho da String. O número de caracteres de uma placa de carro deve ser igual a 7. Colocando essa regra no código:


public static boolean validaPlaca(String placa){
   boolean valido = true;
   if(placa.length() != 7){
      valido = false;
   }
   return valido;
}

Os três primeiros caracteres tem que ser letras. Para validar isso vamos, primeiramente, usar o método substring() da classe String. Este método cria uma String contendo todos os valores desde o primeiro índice passado até o segundo índice menos 1. No nosso caso vamos usar para pegar apenas os três primeiros caracteres da nossa placa. Por enquanto temos isso:


placa.substring(0,3)

Agora precisamos verificar se essa nova String contém apenas letras, para fazer tal verificação vamos usar o método matches(), também da classe String, e passar uma expressão regular como parâmetro. Este método devolve um boolean. Ele verifica se a String que chamou este método se equipara com o parâmetro passado.

No nosso caso, vamos passar a seguinte expressão regular [A-Z]*. Essa expressão só permite as letras de A a Z e todas as letras tem que estar em maiúsculo. Portanto, se a String conter algo diferente do que o permitido pela expressão regular ele retornará false

Vamos usar o método matches() em conjunto com o substring() e encapsular dentro de um if:


if(placa.substring(0, 3).matches("[A-Z]*")){
}

Para finalizar essa validação, vamos negar essa condição, ou seja, só vai entrar no if caso o matches() retorne false, para que possamos alterar o valor de valido para false:


if(!placa.substring(0, 3).matches("[A-Z]*")){
   valido = false;
}

Por fim, vamos usar exatamente os mesmos métodos, substring() e matches(), para validar se os últimos quatro caracteres são dígitos.

A diferença será apenas nos parâmetros passados, para o substring() vamos passar apenas o valor 3, com isso ele pegará o caractere da String com índice 3 e como não passamos um valor final ele irá até o final da String.

Já para o matches(), vamos passar essa expressão regular: [0-9]*, ela só permite números de 0 a 9. Assim, temos:


if(!placa.substring(3).matches("[0-9]*")){
   return false;
}

Pronto, todas as validações foram feitas, nosso método ficou assim:


public static boolean validaPlaca(String placa){
   boolean valido = true;
   if(placa.length() != 7){
      valido = false;
   }
   if(!placa.substring(0, 3).matches("[A-Z]*")){
      valido = false;
   }
   if(!placa.substring(3).matches("[0-9]*")){
      valido = false;
   }
   return valido;
}

Para testarmos, usaremos uma placa válida:


public static void main(String[] args) {
   System.out.println(validaPlaca("FXZ4765"));
}

Como resultado, temos:

Agora vamos passar uma placa válida com “-“, que é a formatação normal de uma placa de carro.


public static void main(String[] args) {
   System.out.println(validaPlaca("FXZ-4765"));
}

Reparem no resultado:

A placa é válida, mas recebemos false, porque? Isso aconteceu pois não prevenimos nosso método contra caracteres especiais ou formatações erradas. Basicamente antes de começar nossas validações devemos tratar a placa recebida para que ela só contenha letras e números.

Para isso vamos usar o método replaceAll() da classe String, que, por sua vez, substitui todos os caracteres passados no primeiro parâmetro pelos caracteres passados no segundo parâmetro.

No nosso caso vamos usar outra expressão regular, essa: [^a-zA-Z0-9]. Com ela no primeiro parâmetro do replaceAll() estamos dizendo que tudo que não for letra de A a Z, seja maiuscula ou minuscula e não for número deve ser substituído. Mas substituído pelo que? Bom, por nada, só queremos tirar esses caracteres da nossa String. Usando esse método nosso código fica assim:


public static boolean validaPlaca(String placa){
   boolean valido = true;
   placa = placa.replaceAll("[^a-zA-Z0-9]", "");
   if(placa.length() != 7){
      valido = false;
   }
   if(!placa.substring(0, 3).matches("[A-Z]*")){
      valido = false;
   }
   if(!placa.substring(3).matches("[0-9]*")){
      valido = false;
   }
   return valido;
}

Vamos testar novamente usando a mesma placa, FXZ-4765:

Pronto, agora funcionou do jeito que queriamos.

Early Return

Só mais um detalhe, olhando nosso método perceba que não importa como venha a placa, passamos por todos os ifs, isso não é muito legal. Por exemplo, se o tamanho da placa for diferente de 7 eu quero que o método acabe aí e retorne false, não tem motivo para passar pelas outras condições, a placa já é inválida.

Então é exatamente isso que vamos fazer. Se a placa for inválida vamos retornar false logo de cara. Isso se chama early return. Vamos refatorar nosso método usando essa técnica:


public static boolean validaPlaca(String placa){
   placa = placa.replaceAll("[^a-zA-Z0-9]", "");
   if(placa.length() != 7){
      return false;
   }
   if(!placa.substring(0, 3).matches("[A-Z]*")){
      return false;
   }
   return placa.substring(3).matches("[0-9]*");
}

Pronto, fizemos nosso método de forma elegante e enxuta.

Conclusão

Validar uma placa é uma tarefa simples, mas vários detalhes podem causar resultados inesperados. Temos, sempre, que prevenir nosso código, pois quando interagimos com o usuário, no nosso caso, recebendo informações vindas dele, não sabemos como o dado chegará para nós.

Também percebemos que não é necessário passar pelo método todo para ter o resultado esperado. Early return é uma boa prática de programação, pois impede que código desnecessário seja executado.

Agora que conhecemos o early return me digam vocês. Quantas vezes vocês já se depararam com códigos desnecessários sendo executados por não fazer uso de tal técnica?

Para conhecer outras técnicas e mais sobre boas práticas no Java, você pode dar uma olhada na Carreira Desenvolvedor Java da Alura, lá você irá se deparar com vários cursos a respeito da linguagem.

FIQUE POR DENTRO

  • Bom post, porém acredito que o título não esta coerente com o conteúdo, não trata-se de verificação e sim de validação. Outro detalhe seria no código mostrado, todo o exemplo pode ser resolvido com apenas uma Regex evitando diversos if’s.

  • Gustavo Souza

    Ótimo post! Porém, caso você procure um padrão DENTRO da String, provavelmente o String.matches() não encontrará, pois ele valida a String como um “bloco”.
    Para validar dentro da String, é melhor usar o Pattern.matcher(), por exemplo:
    Pattern p = Pattern.compile(regex);
    boolean isValido = p.matcher(string).find();
    Caso o padrão seja achado dentro da String, retornará true.

Próximo ArtigoComo o Mobile Learning pode capacitar equipes