quinta-feira, 10 de março de 2016

Expressões Regulares Java - Regex

Olá

Durante meus quase 10 anos de programação com a linguagem Java, não consigo recordar se precisei ou não utilizar expressões regulares... mas durante alguns dos desafios no site HackerRank, fui forçado a estudar para conseguir resolver o desafio que exigia que em uma String X, caso ouve-se pontos(Padrão inglês não tem acentos).

No Site da Oracle existe uma ótima documentação que qualquer um pode ler facilmente a aprender, mas para variar esta em inglês(Sim Jovens Inglês é indispensável).

Segundo a Oracle o que podemos fazer com expressões regulares são pesquisas, edições ou manipulação do texto e dados em Strings;

Vou usar como referencia para dar uma explicada básica o desafio que estava tentando realizar no HackerRank.

Possuía esta entrada:
He is a very very good boy, isn't he?
Que deveria sair com esta saída:
He
is
a
very
very
good
boy
isn
t
he
Em suma precisava retirar a pontuação da frase.
E o próprio enunciado dava a dica sobre usar expressões regulares. Então fui estudar para tentar resolver meu problema.


ConstrutorDescrição
[abc]a, b, or c (Classe Simples)
[^abc]Qualquer carácter exceto a, b, ou c (negação)
[a-zA-Z]a até z, ou A até Z, inclusive (alcance)
[a-d[m-p]]a ate d, ou m até p: [a-dm-p] (Uniao)
[a-z&&[def]]d, e, ou f (interseção)
[a-z&&[^bc]]a até z, exceto para b e c: [ad-z] (subtração)
[a-z&&[^m-p]]a até z, e não m até p: [a-lq-z] (subtração)

 Dai fui testando um a um para ver como se comportam afinal , ver algo funcionando e muito diferente de ler como funciona.

Ai pensei só quero as letras sem  acentos, de cara iria usar a expressão [a-zA-Z] , mas como nada é tao simples, usei o método replaceAll da API String. Ela aceita dois Argumentos, o primeiro um Regex e o segundo a String que ira substituir de acordo com o Regex.

Porem ser usar ele desta forma String.replaceAll("[a-zA-Z]", " "); . Se eu fizer exatamente assim estou dizendo para ele substituir qualquer letra Minuscula ou Maiúscula por Espaço " ";
Meu objetivo e justamente o contrario, então como é o contraio eu vou negar essa regra invertendo a saida dela usando  o simbolo da negação ^ , mudando minha expressao para String.replaceAll("[^a-zA-Z]", " ");

Agora sim tenho a saida que quero sem os Acento. Mas para complementar e explicar como fiz para conseguir as palavras cada uma em uma linha.



String.replaceAll("[^a-zA-Z]", " ").split(" ") adicionando o split(" ") eu tenho como retorno um Array de String[] e com isso posso usar um forEach para percorrer o Array e Imprimir em cada linha cada uma das palavras.

Duvidas ? Comenta ai.