Uma expressão regular é uma forma comum e concisa de representar algum tipo de padrão em texto. Você pode usá-las, por exemplo, com o recurso de “Localizar e Substituir” para fazer alterações rapidamente em um grande volume de dados. Imagine que você tem um documento com milhões de registros de diferentes tipos e deseja buscar todas as datas contidas nele.

Um modo de fazer isso seria usar a expressão regular :

[0-9]{2}[-|\/]{1}[0-9]{2}[-|\/]{1}[0-9]{4}

Assim, você encontraria qualquer uma sequência de números e texto no formato DD-MM-YYYY, por exemplo (neste caso, encontraria mesmo “datas” inválidas, como 32-01-2019). Uma linha e já não é mais necessário percorrer milhares de páginas para obter a informação que se busca.

Pareceu confuso? Não tem problema. Vamos dar uma olhada no básico sobre expressões regulares e depois voltamos neste exemplo, ao final do tutorial.

Você pode aplicar isso em uma variedade de aplicações e linguagens, seja pesquisando em um documento, fazendo operações de ‘Localizar e Substituir’ ou limpando um conjunto de dados. Muitas linguagens de programação e editores de texto/planilha permitem o uso de expressões regulares, de modo que você pode aplicá-las em uma enorme gama de situações. As sintaxes podem diferir levemente de acordo com a linguagem ou programa em uso, mas aqui neste tutorial vamos te passar o básico para você começar a usar Regex no seu dia a dia.

Algumas dicas iniciais

Por mais complicado que expressões regulares possam parecer, elas são todas compostas de partes menores que são usadas para descrever um determinado padrão. Entender estas unidades é simples, porém, antes de começar a aprender a linguagem, tenha em mente algumas coisas:

– Lembre-se sempre que Regex por padrão é case-sensitive: ou seja, faz diferença ESCREVER EM MAIÚSCULAS ou em minúsculas.

– Alguns caracteres em expressões regulares possuem significados especiais. Outros, não. Para dar um significado especial (utilizá-lo como um filtro, por exemplo) a um caractere normal ou para usar um caractere especial (que funciona como um filtro) com significado literal, usamos a barra invertida \ antes deles.

Tudo isto vai ficar mais claro com os exemplos abaixo. Neste tutorial introdutório, vamos dar uma olhada então em alguns tipos de caracteres e suas respectivas funções em expressões regulares.

Na primeira coluna, você tem uma descrição do tipo de caractere. Na segunda, um exemplo de busca utilizando estes caracteres, mostrando em sequência o que esta busca retornaria (terceira coluna) e o que ela não retornaria (quarta coluna). Por fim, explicamos o que está por trás disso tudo.

Você também pode usar este site para testar os comandos abaixo

 

Tipo Busca por.. Retorna… Não retorna… Por quê?
Letras e números gato gato GATO

Gato

grato

Letras e números não possuem significado especial, ou seja, referem-se a eles próprios. A letra “a” refere-se apenas à própria letra minúscula “a”; 3 refere-se ao algarismo “3”, etc. Ao buscarmos por “gato”, o retorno será exatamente os caracteres “g”, “a”, “t”, “o” nesta sequência e em minúsculas.
Números \d

OU

[0-9]

0123456789 um

zero

ou qualquer _ outro caractere alfabético !

Com a barra invertida antes, o “d” “escapa” do seu sentido literal e passa a significar qualquer dígito de 0 a 9
Curinga (ponto) . Todos caracteres, exceto quebras de linhas Um ponto (.) tem um significado especial: ele reconhece todos os caracteres em uma linha.

Ao ser precedido da barra invertida  (\.), ele apenas reconhece o caractere ponto, então ele se torna literal, um caractere sem significado especial.

Curinga (ponto) BRA.IL BRASIL

BRAZIL

BRAKIL

BRASIIL

BRZIL

O ponto (.) também pode ser usado dentro de expressões, servindo como curinga para qualquer caracter

 

Legal, não é? Agora, vamos ver as classes de caracteres.

 

Tipo Busca por.. Retorna… Não retorna… Por quê?
Classes de caracteres Bra[sz]il Brasil

Brazil

BRASIL

Basil

Bravil

Você pode especificar uma classe de caracteres (uma lista de caracteres que se equiparam) ao rodeá-los com colchetes. Outro exemplo: [aeiou] – com isso buscamos qualquer vogal
Intervalo alfabético [A-Za-z]. Qualquer letra (maiúscula ou minúscula) 0123456789

!_@#$%&()

Usando o hífen podemos definir um intervalo numérico, como no exemplo anterior, mas também alfabético
Espaços em branco \s Espaços em branco, como space e tab 0123456789!@_$ O “\s” te permite buscar caracteres “invisíveis” como espaço e tab
Intervalo alfabético com caractere extra [a-z_] Qualquer letra minúscula ou subtraço (underscore) 0123456789 No exemplo, dentro dos colchetes, o “a-z” é um elemento a ser buscado, assim como o subtraço
Todos caracteres de palavras [A-Za-z_] Retorna todos os caracteres de palavras (letras e o subtraço). 0123456789

!_@#$%&()

Tal como no exemplo acima, usamos o hífen para definir um intervalo (todas as letras maiúsculas e minúsculas entre A e Z, além do subtraço)
Negação [^aeiou] Qualquer caractere exceto as cinco vogais brsl Se um acento circunflexo (^) for o primeiro caractere entre colchete, a classe inteira será negada

Se você quiser que sua classe inclua um acento circunflexo literal (em vez de negar todo o resto que esteja lá), você pode usar o escape nele (\^) ou colocá-lo em outro lugar que não seja o começo;

 

Por fim, vamos ver quantificadores e grupos. Você pode cercar uma parte de uma expressão regular por parênteses para tratá-la como uma unidade.

 

Tipo Busca por.. Retorna… Não retorna… Por quê?
Conjunção URSS|RUSSIA URSS

RUSSIA

Ucrânia

PRUSSIA

Use o caractere pipe (|) para dar duas opções para a conjunção
Encapsulamento (REINO UNIDO)|(PAÍS DE GALES) REINO UNIDO

PAÍS DE GALES

REINOUNIDO

REINO

Os parênteses permitem encapsular as regras do seu interior a fim de tratá-las como uma coisa só
Caractere opcional impostos? imposto

impostos

empostos

impostoss

Torna opcional o último caractere antes do ponto de interrogação; ou seja, no exemplo, o caractere “s” pode aparecer zero ou uma vez
Asterisco impostos* imposto

impostos
impostossss

impstossss Já o asterisco permite buscar por zero ou mais ocorrência do caractere especificado anteriormente
Sinal de mais impostos+ impostos
impostossss
imposto Com o sinal de mais, buscamos pelo menos uma ocorrência do caractere ou grupo especificado anteriormente (no exemplo, a letra “s”)
Sinal de chaves vacu{2}m vacuum vacum As chaves servem como multiplicadores, indicando quantas vezes o caractere ou grupo precedente deve aparecer; no exemplo, para dar “match” a letra “u” deve aparecer duas na palavra especificada

 

Mas como isso funciona na prática?

Se você for testar a sequência abaixo em algum editor de texto, lembre-se de conferir se a opção de busca por expressão regular está ativada, caso contrário o software irá interpretar os caracteres literalmente. Vamos ver agora como colocar tudo que abordamos isso de forma integrada em um exemplo real.

Lembra do nosso primeiro exemplo? Mostramos uma expressão regular que identificada o padrão de datas no formato DD-MM-YYYY.

[0-9]{2}[-|\/]{1}[0-9]{2}[-|\/]{1}[0-9]{4}

Vamos decompor a sequência em suas partes menores:

 

[0-9] Significa qualquer caractere numérico entre 0 e 9. Ou seja: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
{2} Com este quantificador, dizemos que o padrão que buscamos precisa repetir duas vezes a descrição anterior: [0-9]

 

Com isto identificamos os dígitos do dia. Repare, no entanto, que o padrão iria encontrar datas “falsas” tais como 88/02/2018 e, por outro lado, não encontraria datas reais que não obedeçam ao formato descrito, por exemplo: 6/03/1988. Neste segundo exemplo, a data não seria localizada pois falta um dígito (zero) no campo “dia”. Mas vamos em frente:

 

[-|\/] Aqui, estou selecionando os caracteres que servem como separador da minha data. Neste caso, escolhe o hífen, a barra vertical e o barra (“/”).

Repare que a barra precisa ser escapada com uma barra invertida “\” antes para ser interpretada corretamente. Visualmente, a junção da barra invertida com a barra normal ( \/ ) lembra a letra V, mas não há esta letra na sequência ao lado.

{1} Defino que o caractere anterior deve aparecer uma única vez

 

Com isto, definimos que o padrão anterior aceita três tipos de separadores, de modo que todas estas diferentes formas de escrever a mesma data seriam encontradas:

03/06/1980

03-06-1980

03|06|1980

Vamos rever nossa fórmula?

[0-9]{2}[-|\/]{1}[0-9]{2}[-|\/]{1}[0-9]{4}

A mesma estrutura já descrita é reutilizada no mês. Para identificar o ano, a única diferença é o número definido para o quantificador: ao invés de um número com 2 caracteres, busco agora um número com formato de 4 caracteres para assim atender ao padrão DD-MM-YYYY.

Saiba mais

Quer se aprofundar mais? Confira esta lista de links especiais que separamos para você:

Recursos didáticos

 

Editores

Regex em linguagens

 

3 thoughts on “Expressão regular pode melhorar sua vida”

  1. Daniel Penalva disse:

    Tem alguma diferença entre o regex descrito aqui e o gnu utilizado no grep por exemplo ?

    trechos como foo2( com regex [o]{2} funciona no site de práticas atual e no grep não

    • Oi Daniel, existem várias implementações diferentes de Regex. Então, sim, a sintaxe pode variar dependendo de onde você vai rodar.

      No manual do grep, por exemplo, vemos que:

      ” grep understands three different versions of regular expression syntax: “basic” (BRE), “extended” (ERE) and “perl” (PCRE)”

      Já no site regexr.com, temos:

      “While the core feature set of regular expressions is fairly consistent, different implementations (ex. Perl vs Java) may have different features or behaviours. RegExr currently supports JavaScript RegExp executed in your browser and PCRE via PHP”

      Espero ter ajudado

  2. Sergio disse:

    Parabéns pelo artigo – muito útil para o dia a dia da programação

Deixe um comentário

O seu endereço de e-mail não será publicado.