Back-End

6 mar, 2009

Expressões regulares em Perl – Parte 01

Publicidade

Uma das ferramentas que eu considero mais poderosas no manuseio de informações de texto são as chamadas expressões regulares, que na prática definem um padrão de formação de alguma informação e, de posse desse padrão, tentando-se “casar” informações com ela. Caso o padrão seja encontrado dentro desse conteúdo, alguma ação é tomada e o processamento segue adiante.

O exemplo prático que sempre gosto de dar é o de CEP, que sempre possui a mesma forma: cinco números, traço, outros três números, algo como 99999-999. Esse formato pode ser utilizado para procurar, dentro de um texto ou outra string qualquer, números de CEP que foram inseridos e que se deseja encontrar agora, para fazer alguma coisa, como inserir as informações numa tabela, por exemplo.

Praticamente toda linguagem de programação moderna possui suporte a expressões regulares, nisso incluem-se JAVA, PHP e, claro, Perl. No caso específico do Perl, o suporte a expressões regulares é o que poderíamos chamar de nativo, pois ele está tão diretamente ligado à sintaxe da linguagem, que praticamente nenhuma função especial é necessária, sendo essa uma das razões para os algoritmos de processamento de texto (que remete às origens da linguagem) serem tão poderosos.

Um item que merece destaque no aprendizado de expressões regulares é que a sintaxe de escrita de uma expressão regular muda pouco de uma linguagem de programação para outra. O que vai mudar é como aplicar ou tratar a estrutura que representa a expressão. Mas, de novo, sabendo como escrever uma expressão (o que de forma alguma é trivial) fica simples usar esse conhecimento em diferentes linguagens.

Não é o objetivo explicar todo conhecimento por trás de expressões regulares nesse artigo, até porque seria impossível, mas mais informações podem ser obtidas em diversos sites da Internet. Eu pessoalmente gosto muito do Aurélio e um outro artigo simples com os principais elementos de expressões regulares pode ser encontrado em Sintaxe Básica de uma ER.

Vamos retornar ao exemplo do CEP. Já sabemos o padrão de formação desse conteúdo. Temos que agora saber como escrever essa representação de tal forma a construir uma expressão regular para “casar” com textos no futuro. Um primeiro esboço seria:


[0-9][0-9][0-9][0-9][0-9]\-[0-9][0-9][0-9]

É bem intuitivo o que foi feito acima. O elemento [0-9] aparece oito vezes, exatamente o número de caracteres numéricos que um CEP possui. Então poderíamos pensar que o símbolo [0-9] representa um número e é exatamente essa a idéia: intervalo de valores numéricos, entre zero e nove. O símbolo “-” foi escapado para ser entendido como traço e não como algum comando válido em expressões regulares e pronto. Ela pode não estar muito simples, mas deve funcionar.

O que essa estrutura vai fazer é tentar encontrar, dentro de algum conteúdo, o padrão por ele definido. Em Perl, qual seria uma maneira de fazer isso?


$str = '88234-999';
if ($str =~ /[0-9][0-9][0-9][0-9][0-9]\-[0-9][0-9][0-9]/) {
  print "casou \n\n";

} else {
  print "NAO casou \n\n";

}

A variável $str está sendo testada para ver se dentro dela, no seu conteúdo, algum trecho casa com a expressão regular definida. Repare no operador =~ que é usado para testar uma variável em função de uma expressão regular. O exemplo vai mostrar que o valor de str casa com o padrão definido. Repare também nos delimitadores da expressão, que nesse caso foram usados barras, mas outros separadores, desde que iguais, poderiam ser usados (como aspas), mas tradicionalmente, com expressões regulares, usam-se barras.

Uma outra máxima de expressões regulares é que sempre existe mais de uma forma de se escrever a mesma expressão (o que também vale para códigos em Perl). Sendo assim, uma outra maneira de se escrever e testar a expressão regular acima, seria:


$str = '88234-999';
if ($str =~ /[0-9]{5}\-[0-9]{3}/) {
  print "casou \n\n";

} else {
  print "NAO casou \n\n";

}

Já nessa sintaxe, repare que as várias repetições de [0-9] foram trocadas por um símbolo entre colchetes que indica o número de vezes que o termo que está à esquerda deve aparecer. No caso, exatamente cinco na primeira e exatamente três na segunda, o que já trouxe uma simplificação na estrutura.

Para finalizar, da mesma forma que o operador =~ serve para tentar casar expressões regulares, o operador !~ serve para negar o operador de casamento. Na prática, ele retorna verdade se e somente se a expressão regular pesquisada não for encontrada no texto mencionado.