quarta-feira, setembro 18, 2024
spot_img
InícioRamos da InformáticaBanco de DadosExpressões regulares, Regex, mais comuns

Expressões regulares, Regex, mais comuns

Expressão regular – ou simplesmente REGEX – é uma sequência de caracteres que define um padrão de busca, é geralmente utilizada dentro de algoritmos de pesquisa de texto para busca e/ou substituição de sequências/padrões de caracteres dentro de strings. Por sua praticidade, está implementada dentro de linguagens de programação, ferramentas e até mesmo alguns aplicativos.

Neste artigo vamos explorar as expressões regulares (regex) mais comuns na programação e no uso de instruções SQL. Ao final, uma lista de feramentas online onde o desenvolvedor pode testar as expressões regulares de acordo com a linguagem de programação que esteja utilizando.

Expressão regular para validar um campo que aceita CPF ou CNPJ (sem cálculo dos dígitos verificadores):

/^([0-9]{3}\.?[0-9]{3}\.?[0-9]{3}\-?[0-9]{2}|[0-9]{2}\.?[0-9]{3}\.?[0-9]{3}\/?[0-9]{4}\-?[0-9]{2})$/

Ela pode ser entendida assim (onde “cpf” é a expressão para validar CPF e “cnpj” é a expressão para validar CNPJ):

/^(cpf|cnpj)$/

As barras inicial e final (/) não fazem parte da expressão propriamente dita – são apenas delimitadores. O caracter ^ no começo e o caracter $ no final exigem que o conteúdo completo do string a ser validado corresponda à expressão entre os mesmos. Os parênteses contendo a barra vertical (a|b) criam uma “opção” alternativa entre “a” e “b“. Satisfazendo qualquer uma das duas expressões, o resultado será positivo. No lugar de “a” e “b“, temos então as expressões específicas para CPF e CNPJ, separadamente.

Para CPF:

[0-9]{3}\.?[0-9]{3}\.?[0-9]{3}\-?[0-9]{2}

A interrogação (?) faz com que a especificação de caractere precedente seja opcional. Portanto os pontos e o tracinho são opcionais. A classe de caracteres [0-9] representa qualquer caracter de 0 a 9 (poderíamos usar \d, mas eu prefiro [0-9] por ser mais legível). Finalmente, o número entre colchetes ({3}) determina uma quantidade específica de vezes que a especificação de caractere precedente deve se repetir. Assim sendo, são requeridos no total 11 caracteres numéricos (3 + 3 + 3 + 2).

Para CNPJ, a estrutura é semelhante:

[0-9]{2}\.?[0-9]{3}\.?[0-9]{3}\/?[0-9]{4}\-?[0-9]{2}

Aqui são requeridos no total 14 caracteres numéricos (2 + 3 + 3 + 4 + 2).

Lembrando que a barra invertida (\) antes do ponto (.) e outros caracteres especiais é um caracter de “escape”, que serve para desconsiderar a interpretação especial do caractere seguinte e considerá-lo literalmente. (O ponto, sem “escape”, significa “qualquer caractere”. Com “escape”, significa meramente o caractere “ponto” mesmo.).

LEIA TAMBÉM: 21 comandos SQL essenciais para programadores e BI

Regex para RG

Valida qualquer RG, incluíndo finais com o dígito X

(^\d{1,2}).?(\d{3}).?(\d{3})-?(\d{1}|X|x$)

Regex para validar e-mail

Primeiramente você precisa aceitar que não será capaz de processar todos os e-mails possíveis. A especificação deles é longa e complicada. Por exemplo, aqui está uma regex que aceita todos os emails e nada mais: http://ex-parrot.com/~pdw/Mail-RFC822-Address.html

Tendo isso em mente, parte-se para fazer uma regex que possa acertar na maioria dos casos.

/^[a-z0-9.]+@[a-z0-9]+\.[a-z]+\.([a-z]+)?$/i

(regexplained)

Seu erro aqui foi apenas o de não incluir o último \. dentro dos parênteses. Fazendo isso tenho esse resultado:

foo.bar@gmail.com       true
foo.bar@gmail.com.br    true
foo.bar@gmail.com.br.br false
foo.bar@gmail.          false
foo.bar@gmailcom        false
foo.bargmail.com        false
@gmail.com                 false

É uma boa alternativo. Mas isso vai falhar em diversos outros casos. Como se o email incluir underlines ou +, ou se o dominio incluir muitos caracteres (como alguns do governo alguem@orgao.uf.gov.br, ).

Uma sugestão mais completa, vinda da especificação do HTML5 pela W3C:

The following JavaScript- and Perl-compatible regular expression is an implementation of the above definition.

/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/

(regexplained)

É importante sempre existir uma validação feita pelo servidor, geralmente enviando um e-mail de confirmação. Usualmente a validação no cliente é usada apenas para melhorar a experiencia de usuário, mostrando o que está errado sem a demora de esperar uma resposta do servidor.

Regex para cartões de crédito

Amex: ^3[47][0-9]{13}$
Aura: /^((?!504175))^((?!5067))(^50[0-9])/
Banese Card: ‘^636117’
Cabal: ‘(60420[1-9]|6042[1-9][0-9]|6043[0-9]{2}|604400)’
Diners: ‘(36[0-8][0-9]{3}|369[0-8][0-9]{2}|3699[0-8][0-9]|36999[0-9])
Discover: /^6(?:011|5[0-9]{2})[0-9]{12}/
Elo: /^4011(78|79)|^43(1274|8935)|^45(1416|7393|763(1|2))|^50(4175|6699|67[0-6][0-9]|677[0-8]|9[0-8][0-9]{2}|99[0-8][0-9]|999[0-9])|^627780|^63(6297|6368|6369)|^65(0(0(3([1-3]|[5-9])|4([0-9])|5[0-1])|4(0[5-9]|[1-3][0-9]|8[5-9]|9[0-9])|5([0-2][0-9]|3[0-8]|4[1-9]|[5-8][0-9]|9[0-8])|7(0[0-9]|1[0-8]|2[0-7])|9(0[1-9]|[1-6][0-9]|7[0-8]))|16(5[2-9]|[6-7][0-9])|50(0[0-9]|1[0-9]|2[1-9]|[3-4][0-9]|5[0-8]))/
Fort Brasil: ‘^628167’
GrandCard: ‘^605032’
Hipercard: ^606282|^3841(?:[0|4|6]{1})0
JCB: /^(?:2131|1800|35\d{3})\d{11}/
Mastercard: ^((5(([1-2]|[4-5])[0-9]{8}|0((1|6)([0-9]{7}))|3(0(4((0|[2-9])[0-9]{5})|([0-3]|[5-9])[0-9]{6})|[1-9][0-9]{7})))|((508116)\\d{4,10})|((502121)\\d{4,10})|((589916)\\d{4,10})|(2[0-9]{15})|(67[0-9]{14})|(506387)\\d{4,10})
Personal Card: ‘^636085’
Sorocred: ‘^627892|^636414’
Valecard: ‘^606444|^606458|^606482’

Visa: ^4[0-9]{15}$

Outras formatações de Regex

Codigo Cor HTML ^#?([a-f]|[A-F]|[0-9]){3}(([a-f]|[A-F]|[0-9]){3})?$ #00ccff
Arquivo de Imagem ^[a-zA-Z0-9-_\.]+\.(jpg|gif|png)$ new-pic_company.jpg
Endereco IP ^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})$ 192.168.0.1
Arquivos Multimedia ^[a-zA-Z0-9-_\.]+\.(swf|mov|wma|mpg|mp3|wav)$ company-presentation.swf
Data Formato Mysql ^\d{4}-(0[1-9]|1[0,1,2])-(0[1-9]|[1,2][0-9]|3[0,1])$ 2012-09-02
Telefone (BR) ^\(?\d{2}\)?[\s-]?\d{4}-?\d{4}$ (11) 5555-1977
Codigo Postal (EUA) ^([A-Z][0-9]){3}$ V2B2S3
Hora (HH:MM) ^([0-1][0-9]|[2][0-3])(:([0-5][0-9])){1,2}$ 12:29
URL ^(http[s]?://|ftp://)?(www\.)?[a-zA-Z0-9-\.]+\.(com|org|net|mil|edu|ca|co.uk|com.au|gov|br)$ http://www.google.com
Telefone Internacional ^(([0-9]{1})*[- .(]*([0-9a-zA-Z]{3})*[- .)]*[0-9a-zA-Z]{3}[- .]*[0-9a-zA-Z]{4})+$ 1.245.532.3422
CEP Brasileiro /^[0-9]{5}-[0-9]{3}$/ 33.300-070
Curso Banco de Dados

 

Expressões regulares em bancos de dados SQL

É bastante utilizado regex em queries SQL no banco de dados.

O operador LIKE até quebra um galho para pesquisas mais simples, com seus metacaracteres % e _. Mas para ir além e fazer pesquisas realmente complexas, é preciso de uma gama de metacaracteres das expressões regulares.

As expressões não fazem parte do padrão SQL, mas alguns bancos de dados já se adiantaram e passaram a suportá-las. Porém, pela falta do padrão, cada banco implementou de seu próprio jeito, o que gerou uma diferença na sintaxe de uso. Nos exemplos seguintes, serão mostradas as sintaxes dos principais bancos.

Suponha que temos um banco de dados com uma tabela chamada veiculos, que traz vários dados sobre cada veículo. A placa do veículo, por exemplo, deve estar no formato AAA-9999. Este é um formato simples, que conseguimos representar com a expressão regular ^[A-Z]{3}-\d{4}$. Para listar todos os veículos cujas placas estão no formato correto:

-- Listar os veículos cujas placas estão no formato AAA-9999

-- MySQL, MariaDB, SQLite
SELECT * FROM veiculos WHERE placa REGEXP '^[A-Z]{3}-\d{4}$';

-- PostgreSQL
SELECT * FROM veiculos WHERE placa ~ '^[A-Z]{3}-\d{4}$';

-- Oracle
SELECT * FROM veiculos WHERE REGEXP_LIKE(placa, '^[A-Z]{3}-\d{4}$');

As coisas ainda estão um pouco bagunçadas, não? Enquanto o SQLite e o MySQL usam o operador REGEXP, o PostgreSQL usa o operador ~ e o Oracle usa uma função REGEXP_LIKE(). Mas tudo bem, use essa colinha para lembrar.

Para fazer uma expressão negada, basta colocar NOT antes do operador, ou no caso do PostgreSQL, usar !~. Voltando ao exemplo anterior, agora buscando os veículos cujas placas não seguem o padrão:

-- Listar os veículos cujas placas NÃO estão no formato AAA-9999

-- MySQL, MariaDB, SQLite
SELECT * FROM veiculos WHERE placa NOT REGEXP '^[A-Z]{3}-\d{4}$';

-- PostgreSQL
SELECT * FROM veiculos WHERE placa !~ '^[A-Z]{3}-\d{4}$';

-- Oracle
SELECT * FROM veiculos WHERE NOT REGEXP_LIKE(placa, '^[A-Z]{3}-\d{4}$');

E que tal se eu te contar que além de pesquisas, você também pode fazer alterações usando expressões regulares? Aí sim, o negócio começa a ficar muito interessante!

O exemplo anterior listou todas as placas que estão fora do padrão AAA-9999. Lembre-se, o usuário é “criativo” na hora de digitar dados, então é comum encontrarmos placas em formatos variados, como AAA 9999, AAA.9999, AAA:9999, AAA9999, …

Em geral, é a aplicação quem faz a limpeza destes dados na hora de mostrá-los na tela, removendo os caracteres indesejados e formatando no padrão correto. Mas você já pode fazer isso na própria consulta SQL, usando substituição de texto com expressões regulares:

-- Mostra o valor original e o formatado como AAA-9999

-- MariaDB
SELECT
  placa AS placa_original,
  REGEXP_REPLACE(placa, '^([A-Z]{3})[.: ]?(\d{4})$', '\\1-\\2') AS placa_ok
FROM veiculos;

-- PostgreSQL
SELECT
  placa AS placa_original,
  regexp_replace(placa, '^([A-Z]{3})[.: ]?(\d{4})$', '\\1-\\2') AS placa_ok
FROM veiculos;

-- Oracle
SELECT
  placa AS placa_original,
  REGEXP_REPLACE(placa, '^([A-Z]{3})[.: ]?(\d{4})$', '\1-\2') AS placa_ok
FROM veiculos;

Que tal ir um passo além, e já corrigir estes dados diretamente no banco de uma vez? Assim, eles já estarão sempre corretos e ninguém mais precisará se preocupar em formatá-los posteriormente.

Primeiro, você aplica a técnica do exemplo anterior, de usar o SELECT para mostrar o valor original e o novo, e vai com calma, ajustando sua expressão regular até ela ficar perfeita, formatando corretamente 100% dos casos. Depois, você utiliza a mesma expressão no UPDATE, corrigindo de uma vez todos os dados:

-- Corrigir todas as placas para o formato AAA-9999

-- MariaDB
UPDATE veiculos
SET placa = REGEXP_REPLACE(placa, '^([A-Z]{3})[.: ]?(\d{4})$', '\\1-\\2');

-- PostgreSQL
UPDATE veiculos
SET placa = regexp_replace(placa, '^([A-Z]{3})[.: ]?(\d{4})$', '\\1-\\2');

-- Oracle
UPDATE veiculos
SET placa = REGEXP_REPLACE(placa, '^([A-Z]{3})[.: ]?(\d{4})$', '\1-\2');

Se você também já perdeu muito tempo de vida fazendo faxina nos dados do banco, sabe que poder usar expressões regulares nestes casos NÃO TEM PREÇO.

E assim, vamos aos poucos resolvendo os problemas causados por pessoas, sistemas e migrações.

 

Mais sobre banco de dados, acesse a seção: Banco de Dados

Testadores online

  1. Regex101 – Atualiza enquanto digita, destaca texto casado, mostra o conteúdo dos grupos, faz substituição de textos, referência rápida, sintaxes JavaScript, Python e Perl.
  2. RegexPal – Atualiza enquanto digita, destaca texto casado, referência rápida, sintaxe JavaScript.
  3. Debuggex – Cria um gráfico de sua expressão regular. Bom para entender como sua expressão é interpretada pelo computador. Sintaxe JavaScript, Python e PCRE.
  4. Testador de Expressões Regulares – Interface em português, atualiza enquanto digita, mostra se casou ou não usando cores, sintaxe JavaScript.
  5. Rubular – Atualiza enquanto digita, destaca texto casado, referência rápida, sintaxe Ruby.
  6. RegExr Atualiza enquanto digita, destaca texto casado, referência rápida, precisa do Flash Player 9, sintaxe ActionScript.
  7. Regex Powertoy – Atualiza enquanto digita, destaca texto casado, referência rápida, sintaxe Perl e Java.
  8. regex – Atualiza enquanto digita, destaca texto casado, referência rápida, mostra código pronto da linguagem, sintaxe JavaScript, Perl, Python e PHP.
  9. HiFi RegExp Tool – Atualiza enquanto digita, destaca texto casado, referência rápida, exemplo de código em JavaScript, sintaxe JavaScript.
  10. JRX Atualiza enquanto digita, destaca texto casado, referência rápida, sintaxe JavaScript.
  11. Nregex Atualiza enquanto digita, destaca texto casado, referência rápida, sintaxe C#.NET.
  12. Regex Mate Atualiza com botão (estilo console), sintaxe JavaScript.
  13. My Regex Tester Destaca texto casado, explica a expressão, otimiza a expressão, mostra código pronto da linguagem, sintaxe JavaScript, Java, VB.NET, C#.NET, PHP e ASP.
  14. Regexper – Cria diagramas que descrevem o funcionamento de uma expressão regular.
  15. Regular Expression Generator – Gerador de Expressões Regulares. Você digita o texto que quer casar e ele gera um programa pronto para extrair este texto, em várias linguagens, entre elas Python, Perl, PHP, Ruby, Java e javaScript.
  16. Regular Expression Analyzer – Analisador de expressões, que gera uma árvore de sua estrutura, ficando fácil entendê-la. Sintaxe Java, JavaScript e Perl.
  17. reAnimator Cria um gráfico (autômatos finitos) de sua expressão regular. Bom para entender como sua expressão é interpretada pelo computador.
  18. Regexplained Fontes gigantescas, design estiloso. Bom para testes rápidos com strings pequenas.
  19. RegexOne – Tutorial com exemplos interativos que a cada lição vai te ensinando um pouco sobre as expressões.

 

Gostaria de saber de alguma outra expressão regular ou adicionar aqui a este artigo?

Leia também:

Ramos da Informática
Ramos da Informáticahttps://ramosdainformatica.com.br
Ramos da Informática é um hub de comunidade sobre linguagens de programação, banco de dados, DevOps, Internet das Coisas, tecnologia da indústria 4.0, Cyber Segurança e Startups.
ARTIGOS RELACIONADOS
- Advertisment -spot_img

MAIS LIDOS

Sua assinatura não pôde ser validada.
Você fez sua assinatura com sucesso.

E-Zine Ramos da Informática

Assine o E-Zine e tenha Conteúdo Exclusivo, Concursos para assinantes, descontos exclusivos e uma área de conteúdos exclusivos só do E-zine.