23.6.05

Regular Expressions

Suponha que você tenha uma string contendo pares nome/valor e alguma formatação e deseje extrair esses dados. Utilizando o pacote java.util.regex, incluso no JVM desde a versão 1.4 é possível realizar essa operação de maneira simples (sim, aquela matéria chata da aula de compiladores serve para alguma coisa!).

Observe o código abaixo. Note que a string content possui dados formatados de maneira aleatória, com quantidade variável de espaços, quebras de linha e tabulações.
 
String exp = "([A-Z]\\w{1,3}):\\s*(\\S*)(?:\\s||\\z|\\t])";
1 String content = "Val1: 1 Val2: 2 \tVal3: 3 " +
"\rVal4: 4 Val5: 5.5 Val6: 6 Val7: 7";

2 Pattern pattern = Pattern.compile(exp);
3 Matcher matcher = pattern.matcher(content);

4 while (matcher.find()) {
//uma das coisas mais cool do C agora em java! \o/
5 System.out.printf("Match:'%s'\tAttrib:'%s'\tValue:'%s'\n",
matcher.group(0), matcher.group(1), matcher.group(2));
6 }

O primeiro passo para o uso de regular expressions é compilar a sua expressão em um pattern (2). O pattern então é aplicado ao conteúdo, obtendo-se um objeto Matcher, que é o mecanismo de operação (3). A chamada de método da linha 4 procura a próxima ocorrência da expressão dentro do conteúdo. Caso seja encontrada, o parser a armazena em grupos.

Para visualizar melhor o funcionamento dos grupos, vamos considerar o primeiro par. O grupo de índice 0 contém a ocorrência inteira, no caso 'Val1: 1 '. Os grupos são denotados na expressão regular pelo uso de parênteses e são numerados da esquerda para a direita. Ou seja: o grupo 1 contém 'Val1' e o grupo 2 contém '1'. Nesse exemplo apenas 2 grupos são capturados, uma vez que o prefixo '?:' indica um grupo que não gera captura.

A execução do código gera o seguinte output:

Match:'Val1: 1 ' Attrib:'Val1' Value:'1'
Match:'Val2: 2 ' Attrib:'Val2' Value:'2'
Match:'Val3: 3 ' Attrib:'Val3' Value:'3'
Match:'Val4: 4 ' Attrib:'Val4' Value:'4'
Match:'Val5: 5.5 ' Attrib:'Val5' Value:'5.5'
Match:'Val6: 6 ' Attrib:'Val6' Value:'6'
Match:'Val7: 7' Attrib:'Val7' Value:'7'

E todo o parsing é executado em módicos 4,5 ms em um Pentium M 1,6 GHz, em média.

Obs: para detalhes sobre a sintaxe de expressões regulares veja o javadoc da classe Pattern.

Nenhum comentário: