Expressões Regulares
Introdução
O módulo re do Python permite identificar padrões dentro de strings. Esse recurso é bastante usado na análise dos dados coletados na raspagem de dados (web scraping). Basicamente, o programa fornece a string e o padrão a ser procurado, o Python então verifica se há uma combinação.

São exemplos de métodos/atributos disponibilizados pelo módulo re:
- findall() – retorna uma lista de todas as correspondências encontradas;
- search() – retorna a primeira correspondência encontrada;
- match() – verifica se o padrão combina com o início do alvo;
- split() – divide a string em uma lista, dividindo-a onde quer que haja correspondência com o padrão;
- sub() – encontra todas as substrings que correspondem com o padrão e faz a substituição por uma string diferente.
Como exemplo, considere o módulo re e a variável msg que possui uma string (usado como o alvo).
import re msg="""E agora, José? A festa acabou, a luz apagou, o povo sumiu, a noite esfriou, e agora, José? e agora, você? você que é sem nome, que zomba dos outros, você que faz versos, que ama, protesta?
Podemos verificar se o padrão “José” existe no alvo da seguinte forma:
padrao = 'José' exp = re.compile(padrao) resultado = exp.findall(msg) print(resultado)
Neste caso, a expressão regular ‘José’ é compilada no objeto padrão exp. O método findall() procura pelo padrão (‘José’) no alvo (‘msg’) e retorna o resultado. A resposta é
['José', 'José', 'José']
É possível definir que o padrão não é case sensitive com
exp = re.compile(padrao, re.IGNORECASE)
Assim, o programa dará a mesma resposta, mesmo que a variável padrao seja igual a ‘JOSÉ’. Abaixo, é mostrada outra forma de pesquisar pelo padrão sem usar re.compile(). O resultado obtido pelo programa é o mesmo.
padrao = 'JOSÉ' resultado = re.findall(padrao, msg, re.IGNORECASE) print(resultado)
Para mais detalhes sobre expressões regulares em Python, veja https://docs.python.org/pt-br/3.8/howto/regex.html.
Metacaracteres
Um metacaractere é um caractere que tem um significado especial para o programa.
- Ponto: .
Esse metacaractere substitui um único caractere. Veja o exemplo abaixo.
import re msg="""E agora, José? A festa acabou, a luz apagou, o povo sumiu, a noite esfriou, e agora, José? e agora, você? você que é sem nome, que zomba dos outros, você que faz versos, que ama, protesta? e agora, José?""" padrao1 = 'a.a.ou' resposta = re.findall(padrao1, msg) print("*** Padrão 1") print(resposta, "\n") padrao2 = '....ou' resposta = re.findall(padrao2, msg) print("*** Padrão 2") print(resposta)
A resposta é
*** Padrão 1 ['acabou', 'apagou'] *** Padrão 2 ['acabou', 'apagou', 'sfriou', 'dos ou']
Portanto, o primeiro padrão procura por uma substring com 6 caracteres onde o primeiro e o terceiro caracteres são ‘a’ e o quinto e o sexto caracteres correspondem a ‘ou’. O segundo padrão procura uma substring de 6 caracteres onde o quinto e o sexto caracteres correspondem a ‘ou’.
- Lista: [ ]
Esse metacaractere permite definir um conjunto de caracteres que pode aparecer na posição especificada.
import re msg="""E agora, José? A festa acabou, a luz apagou, o povo sumiu, a noite esfriou, e agora, José? e agora, você? você que é sem nome, que zomba dos outros, você que faz versos, que ama, protesta? e agora, José?""" padrao1 = 'a[abc]a[abc]ou' resposta = re.findall(padrao1, msg) print("*** Padrão 1") print(resposta, "\n") padrao2 = 'a[a-z]a[bg]ou' resposta = re.findall(padrao2, msg) print("*** Padrão 2") print(resposta, "\n") padrao3 = 'a[^c]a[a-z]ou' resposta = re.findall(padrao3, msg) print("*** Padrão 3") print(resposta, "\n") padrao4 = 'Jos[a-zá-ü]' resposta = re.findall(padrao4, msg) print("*** Padrão 4") print(resposta, "\n")
O primeiro padrão define que os caracteres ‘a’, ‘b’ e ‘c’ podem aparecer na segunda e na terceira posições. O segundo padrão permite que qualquer letra minúscula apareça na segunda posição e que os caracteres ‘b’ e ‘g’ podem aparecer na quarta posição. O terceiro padrão define que o caractere ‘c’ não pode aparecer na segunda posição e que qualquer letra minúscula pode aparecer na quarta posição. O quarto padrão especifica que qualquer letra minúscula, acentuada ou não, pode aparecer após “Jos”. O programa mostra a resposta abaixo.
*** Padrão 1 ['acabou'] *** Padrão 2 ['acabou', 'apagou'] *** Padrão 3 ['apagou'] *** Padrão 4 ['José', 'José', 'José']
A tabela abaixo mostra exemplos de conjunto de caracteres que pode ser usado para substituir as classes POSIX (não definidas no Python).
Classe Posix | Python | Significado |
[:upper:] | [A-ZÀ-Ü] | Letras maiúsculas (com e sem acentuação) |
[:lower:] | [a-zà-ü] | Letras minúsculas (com e sem acentuação) |
[:alpha:] | [A-Za-zÀ-ü] | Maiúsculas/minúsculas (com e sem acentuação) |
[:alnum:] | [A-Za-zÀ-ü0-9] | Letras e números |
[:digit:] | [0-9] | Números |
- Lista negada: [^]
No exemplo acima, o terceiro padrão define que o caractere ‘c’ não pode aparecer na segunda posição com [^c]. Por isso a resposta mostra apenas a substring ‘apagou’ (não mostra ‘acabou’). Se o programa tivesse usado o padrão [^cp], nem “c’ e nem ‘p’ poderiam aparecer na segunda posição e a resposta da busca seria uma lista vazia.
- Opcional: ?
Esse metacaractere define que o caractere antes de ? pode ou não existir no padrão.
import re msg="naturalmente, a natureza é natural e natureba" padrao1 = 'natura?' resposta = re.findall(padrao1, msg) print("*** Padrão 1") print(resposta, "\n") padrao2 = 'nature?' resposta = re.findall(padrao2, msg) print("*** Padrão 2") print(resposta, "\n") padrao3 = 'natureb?a' resposta = re.findall(padrao3, msg) print("*** Padrão 3") print(resposta, "\n") padrao4 = 'nature[a-z]?' resposta = re.findall(padrao4, msg) print("*** Padrão 4") print(resposta, "\n")
O primeiro padrão procura por “natur” e “natura” no alvo. O segundo padrão procura por “natur” e “nature”. O terceiro padrão procura por “natureba” e “naturea”. O quarto padrão procura por uma substring que começa por “nature” e pode ter um caractere qualquer na sétima posição. A resposta é
*** Padrão 1 ['natura', 'natur', 'natura', 'natur'] *** Padrão 2 ['natur', 'nature', 'natur', 'nature'] *** Padrão 3 ['natureba'] *** Padrão 4 ['naturez', 'natureb']
- Asterisco: *
Esse metacaractere define que o caractere antes de * pode ocorrer zero, uma ou mais vezes.
import re msg='1227 122228 104 1222222226 1632323' padrao1 = '12*6' resposta = re.findall(padrao1, msg) print("*** Padrão 1") print(resposta, "\n") padrao2 = '12*' resposta = re.findall(padrao2, msg) print("*** Padrão 2") print(resposta, "\n")
O primeiro padrão procura por substrings que começam com ‘1’, têm uma quantidades indefinida de caracteres ‘2’ e no final têm o caractere ‘6’. O segundo padrão começa com ‘1’ e tem, em seguida, um numero indefinido de caracteres ‘2’.
*** Padrão 1 ['1222222226', '16'] *** Padrão 2 ['122', '12222', '1', '122222222', '1']
- Mais: +
Esse metacaractere define que o caractere antes de + pode ser repetido inúmeras vezes.
import re msg='1227 122228 104 1222222226 1632323' padrao1 = '12+6' resposta = re.findall(padrao1, msg) print("*** Padrão 1") print(resposta, "\n") padrao2 = '12+' resposta = re.findall(padrao2, msg) print("*** Padrão 2") print(resposta, "\n")
O primeiro padrão procura por substrings que começam com ‘1’, têm um ou mais caracteres ‘2’ e no final têm o caractere ‘6’. O segundo padrão começa com ‘1’ e é seguido por um ou mais caracteres ‘2’.
*** Padrão 1 ['1222222226'] *** Padrão 2 ['122', '12222', '122222222']
- Chaves: { }
Esse metacaractere define quantas vezes o caractere antes das chaves deve aparecer nos substrings.
import re msg='1227 122228 104 1222222226 1632323' padrao1 = '12{3}' resposta = re.findall(padrao1, msg) print("*** Padrão 1") print(resposta, "\n") padrao2 = '12{0,4}' resposta = re.findall(padrao2, msg) print("*** Padrão 2") print(resposta, "\n") padrao3 = '12{2,}' resposta = re.findall(padrao3, msg) print("*** Padrão 3") print(resposta, "\n")
O primeiro padrão procura por substrings que começam com o caractere ‘1’ e têm, em seguida, três caracteres ‘2’. O segundo padrão tem de zero a 4 caracteres ‘2’ após o primeiro caractere ‘1’. O terceiro padrão tem o caractere ‘1’ e dois ou mais caracteres ‘2’.
*** Padrão 1 ['1222', '1222'] *** Padrão 2 ['122', '12222', '1', '12222', '1'] *** Padrão 3 ['122', '12222', '122222222']
- Circunflexo: ^
Esse metacaractere verifica se existe um determinado padrão no início de uma string.
import re msg="E agora, José? A festa acabou, a luz apagou, o povo sumiu, a noite esfriou" padrao1 = '^E agora' resposta = re.findall(padrao1, msg) print("*** Padrão 1") print(resposta, "\n") padrao2 = '^A festa acabou' resposta = re.findall(padrao2, msg) print("*** Padrão 2") print(resposta, "\n")
O primeiro padrão consiste na substring ‘E agora’, enquanto o segundo padrão consiste na substring ‘A festa acabou’. O primeiro padrão é encontrado nos primeiros caracteres do alvo. O segundo padrão não é encontrado no início do alvo.
*** Padrão 1 ['E agora'] *** Padrão 2 []
- Cifrão: $
Esse metacaractere verifica a existência de um determinado padrão no final de uma linha.
import re msg="E agora, José? A festa acabou, a luz apagou, o povo sumiu, a noite esfriou" padrao1 = 'esfriou$' resposta = re.findall(padrao1, msg) print("*** Padrão 1") print(resposta, "\n") padrao2 = '.{15}$' resposta = re.findall(padrao2, msg) print("*** Padrão 2") print(resposta, "\n")
O primeiro padrão verifica se a substring ‘esfriou’ é encontrada no final da linha. O segundo padrão verifica os últimos 15 caracteres da linha.
*** Padrão 1 ['esfriou'] *** Padrão 2 ['a noite esfriou']
- Borda de palavra: \b
Esse metacaractere define o início ou um fim de uma palavra.
import re msg='arma, armação, armadilha' resposta = re.findall(r"\barma", msg) print("*** Padrão 1") print(resposta, "\n") resposta = re.findall(r"arma\b", msg) print("*** Padrão 2") print(resposta, "\n")
O primeiro padrão procura pelo substring ‘arma’ no início das palavras e acha três palavras. O segundo padrão procura por ‘arma’ no final das palavras e só encontra uma palavra. Note que o caractere “r” é colocado no início da definição dos padrões. Isto indica para o Python não interpretar “\b” como backspace. Assim “\b” é considerada uma substring de dois caracteres contendo um caractere “\” e um caractere “b”. O caractere “r”, neste caso, corresponde à notação de string crua (raw).
*** Padrão 1 ['arma', 'arma', 'arma'] *** Padrão 2 ['arma']
O uso de “\B” no padrão significa que a substring não é uma borda de palavra. Assim, para verificar que “rma” não está no início de uma palavra, basta usar
resposta = re.findall(r"\Brma", msg) print(resposta, "\n")
- Escape: \
O Escape tira o poder de um metacaractere.
import re msg="Em uma lista, \n todo mundo é normal: *?.\}" resposta = re.findall(", \n", msg) print("*** Padrão 1") print(resposta, "\n") resposta = re.findall("[\*\.]", msg) print("*** Padrão 2") print(resposta, "\n")
O primeiro padrão procura por “\n” (quebra de linha), ou seja, procura por dois caracteres “\” e “n”. Neste caso, o primeiro caractere não é interpretado como escape (não existe definição de sequência especial “\n”). O segundo padrão procura pelo asterisco e pelo ponto e “\” é o metacaractere escape, pois existem os metacaracteres asterisco e ponto.
*** Padrão 1 [', \n'] *** Padrão 2 ['*', '.']
- Ou: |
Esse metacaractere corresponde ao operador lógico OU.
import re msg="Em uma lista, \n todo mundo é normal: *?.\}" resposta = re.findall("lista|normal|\*", msg) print(resposta, "\n")
O padrão procura por “lista”, “normal” ou asterisco.
['lista', 'normal', '*']
- Grupo: ( )
Esse metacaractere serve para agrupar as expressões contidas dentro deles. Dessa forma, é possível repetir o conteúdo de um grupo com um qualificador de repetição como , +, ? e { }. No exemplo abaixo, o padrão procura por uma palavra que tenha hífen, antes e depois do hífen pode existir qualquer número de letras (minúsculas e maiúsculas)
import re msg='''Sistemas de informação são descritos em termos de suas dimensões tecnológica, organizacional e humana, o que exige uma abordagem multidisciplinar. Nosso curso BSI-UNIRIO propicia uma formação básica sólida em Sistemas de Informação, Ciência da Computação e Matemática, além de propiciar formação com ênfase no estudo das tecnologias, das organizações e de fatores humanos.''' padrao = re.compile(r'([a-z]+)-([a-z]+)', re.IGNORECASE) resposta = re.search(padrao, msg) print("*** Informação sobre o objeto 'resposta'") print(resposta, "\n") print("*** Todo o string encontrado") print(resposta.group(0), "\n") print("*** Parte do string antes de '-'") print(resposta.group(1), "\n") print("*** Parte do string depois de '-'") print(resposta.group(2), "\n")
A resposta é
*** Todo o string encontrado BSI-UNIRIO *** Parte do string antes de '-' BSI *** Parte do string depois de '-' UNIRIO
- Retrovisor: \1
Esse metacaractere armazena os grupos de dados encontrados de acordo com o padrão informado. No máximo podem ser definidos 9 grupos de dados (contados da esquerda para direita). No exemplo abaixo, o padrão é composto por dois grupos separados por um hífen. O primeiro grupo é representado por \1 e o segundo grupo por \2. O método sub() é usado para alterar msg.
import re msg = 'Cursos: BSI-CCET, História-CCH, Medicina-CCBS' resposta = re.findall(r'([A-Za-zÀ-ü]+)-([A-Za-zÀ-ü]+)', msg) print(re.sub(r'([A-Za-zÀ-ü]+)-([A-Za-zÀ-ü]+)', r'\1 - Graduação', msg), "\n") print(re.sub(r'([A-Za-zÀ-ü]+)-([A-Za-zÀ-ü]+)', r'\2 - Unidade gestora', msg), "\n")
A resposta é
Cursos: BSI - Graduação, História - Graduação, Medicina - Graduação Cursos: CCET - Unidade gestora, CCH - Unidade gestora, CCBS - Unidade gestora
Observações
Primeira observação: As sequências especiais consistem em ‘\’ e um caractere. Se o caractere não for um dígito ASCII ou uma letra ASCII, o resultado corresponderá ao segundo caractere. Por exemplo, \$ corresponde ao caractere ‘$’. Na seção acima, foram discutidas algumas sequências especiais. Outras sequências podem ser vistas abaixo.
- \A – corresponde ao início do string;
- \d – corresponde ao dígito decimal (classe [0-9]);
- \D – corresponde ao não dígito (classe [^0-9]);
- \S – corresponde a qualquer caractere que não seja um caractere de espaço em branco;
- \w – corresponde ao caractere alfanumérico (classe [azA-Z0-9_]);
- \W – corresponde a qualquer caractere não alfanumérico ([^a-zA-Z0-9_]);
- \Z – corresponde ao final do string.
Segunda observação: A tabela abaixo mostra os metacaracteres chamados universais.
Metacaractere | Especificação | Significado |
. | Ponto | Qualquer caractere |
* | Asterisco | Qualquer quantidade |
.* | Ponto e asterisco | Qualquer coisa |