Pedro F. Carvalho Analista de Sistemas [email protected] Para a Ciência da Computação Expressões Regulares(ERs ou do inglês abreviado regex - regular expression) provê uma forma eficiente de identificar e manusear cadeias de caracteres de interesse, como caracteres particulares, seqüências alfanuméricas, padrões numéricos, etc... Dessa forma podemos, por exemplo, utilizar ERs para: Localizar um determinado trecho de texto que só se tem idéia das variações possíveis. Procurar seqüências alfanuméricas que se iniciem ou terminem com caracteres conhecidos. Realizar busca com padrões complexos de combinações alfanuméricas. Validação de formatos de texto Filtragem de informação. Para utilização de Expressões Regulares, se faz necessário conhecer alguns metacaracteres( entenda por “curingas” ou “alias”) que são encontrados na utlização de ERs, nesse instante apenas sitarei alguns realações mais completas poderão ser encontradas a apartir das referências no final do artigo. Para utilização de expressões regulares existem vários metacaracteres que devem ser conhecidos, entre eles: Metacaracter Função Exemplo \ Escape \\ corresponde a \ ^ Posição inicial da Linha(String) ^A corresponde a que se deseje as strings que se iniciem com A $ Posição final da Linha(String) $B corresponde a que se deseje as strings que terminem com B [] Lista [abc] a string deve conter qualquer dos caracteres da lista . Qualquer caractere Funciona como um “coringa” trazendo qualquer resultado, por exemplo: n.o trará qualquer resultado como não ou nao {n} Número de caracteres | Alternativa (similar a ou) Alternativa de padrão de busca, por exemplo (‘joão’|’maria’) Pedro F. Carvalho Analista de Sistemas [email protected] O Oracle versão 10G , ou superior, possui as seguintes funções de busca baseada no uso de expressões regulares: REGEXP_LIKE(),REGEXP_REPLACE(),REGEXP_SUBSTR() e REGEXP_COUNT(), essa última novidade da versão 11G. REGEXP_LIKE(x, padrão[,opção_correspondente]) - Realiza a busca em x da expressão regular definida no parâmetro padrão. Opção_correspondente pode ser definida com os seguintes valores: • • • • • ‘c’ - Especifica correspondência com diferenciação de maiúsculas e minúsculas( Padrão – case-Sensitive) ‘i’ - Especifica a busca sem diferenciação de caracteres maiúsculos e minúsculos(case-Insensitive) ‘n’ - Que permite usar o operador de correspondência com qualquer caractere. ‘m’ - Que trata x como uma linha múltipla. ‘x’ - ignora espaços em branco. A semelhança com o comando LIKE não é mera coincidência, mas o leitor já poderá notar a maior flexibilidade no uso de REGEXP_LIKE em relação ao operador LIKE. Considerando que a melhor maneira de aprender é com a utilização prática, estarei ilustrando a utilização com vários pequenos exemplos de uso, que poderão ser estudados e adaptados a outras necessidades. Nesse primeiro exemplo suponhamos a necessidade de achar em uma tabela de clientes todos os clientes com data de nascimento entre 1970 e 1975. Podemos realizar a busca, usando expressões regulares, da seguinte forma: SELECT nome, sobrenome, data_nascimento FROM clientes WHERE REGEXP_LIKE(TO_CHAR(data_nascimento, 'YYYY'), '^197[0-5]$'); Devemos ter em mente que ERs, ao contrário do operador LIKE, tem a tendência de nos trazer tudo, sem a necessidade dos coringas (%), dessa forma precisamos estar atentos para restringir a informação de retorno ao desejado. Para quem não tem ainda experiência com expressões regulares, podemos definir, como exemplo, um conjunto numérico de muitas formas, de forma que [0123456789] é igual à [0-9], esses detalhes podem tornar seu código muito mais legível e elegante, e economizar digitação é claro. No exemplo anterior poderíamos ler a expressão da seguinte forma, retorne todos os clientes (nome, sobrenome, data de nascimento), cujo ano de nascimento se inicie com 197(“^197”) e termine (“$” ) com um elemento de 0 até 5 (“[0-5]$”). Pedro F. Carvalho Analista de Sistemas [email protected] Outro exemplo de recuperação de registros dos clientes, podemos ter a necessidade de recuperar em uma base qualquer os clientes cujo sobrenome se iniciem com ‘C’ ou ‘c’, realmente um exemplo simples. Nesse caso podemos lançar mão, por exemplo, do seguinte código, onde observem o metacaracter “^” garante a busca no inicio do campo e a opção correspondente “i” uma busca case-insensitive: SELECT nome, sobrenome, data_nascimento FROM clientes WHERE REGEXP_LIKE(sobrenome, '^C’, ‘i’); Para recuperar os registros dos clientes que se chamem Flávio ou Flavio, podemos usar o seguinte o código: SELECT nome, sobrenome, data_nascimento FROM clientes WHERE REGEXP_LIKE(nome , '^FL[aá]’, ‘i’); Note nesse caso que os elementos da lista “a ou “á” não possuem separadores e que a busca é case-insentive. Nesse ponto muitos podem colocar que esse mesmo tipo de busca pode ser feita por meio de LIKE em SQL ou por meio de buscas textuais. Nesse instante devemos pensar que para cada caso existe uma solução mais adequada, e que para nesses exemplos a solução mais simples elegante é realmente lançar mão das ERs, mas deixo bem claro que existirão situações que a utilização de soluções textuais, fonéticas, ou até mesma a combinação de várias dessas técnicas combinadas ainda com Ers, poderão se mostrar úteis ou até mesmo necessárias. Continuando com nossos exemplos, podemos trazer uma seleção de linhas em que o nome possua exatamente cinco letras: SELECT nome FROM clientes WHERE REGEXP_LIKE(nome , '^.....$','i'); Podemos observar que o número de caracteres desejadas também poderia ser expresso da seguinte maneira, no bloco WHERE da nossa expressão: REGEXP_LIKE(nome, '^.{5}$','i'); Pedro F. Carvalho Analista de Sistemas [email protected] Nesse momento vamos supor que queremos procurar dois nomes ao mesmo tempo, ou ‘joão’ ou ‘maria’: SELECT nome FROM clientes WHERE REGEXP_LIKE(nome , '(joão|maria)','i'); Estes exemplos simples tiveram como objetivo, demonstrar tanto a versatilidade quanto a simplicidade das ERS, e como sua utilização pode se expandir para expnadir para muito além do nosso conhecido comando LIKE. Não poderíamos deixar de citar que podemos lançar mão de ERs nos SGBDs para outras funções que não somente a busca, podemos utiliza-los, por exemplo para restringir entradas nos SGBDs. Para tanto podemos utilizar também as ERs para construção de constraints, por exemplo, para definir o formato que o números de telefones devem ser armazenados no SGBD, por exemplo (xxx) xxx-xxxxx, poderíamos lançar mão do seguinte comando: ALTER TABLE cliente ADD (CONSTRAINT formato_numero_telefone CHECK (REGEXP_LIKE(numero_telefone, '^\([[:digit:]]{3}\) [[:digit:]]{3}-[[:digit:]]{4}$'))); Além de REGEXP_LIKE o Oracle disponibiliza as seguintes funções com suporte a expressões regulares: • REGEXP_REPLACE() – O uso dessa função é para procurar um padrão e substituí-lo por um string dada • REGEXP_SUBSTR() – Retorna parte de uma string com recursos avançados. estende as funcionalidades da função SUBSTR, deixando você pesquisar uma string para uma expressão regular padrão. Esta função é útil se você precisar o conteúdo de uma string, mas não corresponder a sua posição na string original. A função retorna a string como VARCHAR2 ou CLOB. • REGEXP_COUNT() –Novidade do Oracle 11G - , Usado para obter a quantidade de vezes que uma expressão regular ocorre em uma string. Pedro F. Carvalho Analista de Sistemas [email protected] As expressões regulares possuem várias vantagens sobre os tradicionais comandos SQLs (LIKE, INSTR, SUBSTR e REPLACE) desses apenas o operador LIKE possui facilidades de busca ( % e _ ), e mesmo assim não suporta mecanismos de busca de padrões ou expressões complexas, sendo muito difícil reproduzir expressões regulares complexas com comandos SQL IV – E quanto a índices? Todos sabemos que os índices são um fator muito importante na busca de informações em função da melhor desempenho que podem proporcionar as buscas. Assim como com a utilização em SGBDs do comando LIKE , os índices padrões criados em um determinado campo não são utilizados nas buscas por ERs, no entanto, isso é muito importante, você pode criar índices baseados em função para implementar desempenho em suas consultas com ERs, caso contrário suas consultas com ERs farão uma varredura completa na tabela(full table scan) o que poderá causar contenção no banco de dados.