Expressões Regulares em Python — 2025 | Python Brasil

Aprenda expressões regulares em Python com o módulo re. Padrões, validação e extração de dados com exemplos. Confira!

5 min de leitura Equipe Python Brasil

Expressões regulares (regex) são sequências de caracteres que definem padrões de busca em textos. Elas são uma ferramenta indispensável para qualquer programador que precise validar entradas, extrair informações ou transformar strings de maneira eficiente. Em Python, o módulo re da biblioteca padrão oferece suporte completo a expressões regulares.

Apesar da fama de serem difíceis de aprender, as expressões regulares seguem uma lógica consistente. Neste artigo, vamos desmistificar o assunto e mostrar como usar regex em situações práticas do dia a dia.

O módulo re e funções básicas

O módulo re oferece diversas funções para trabalhar com padrões. As mais utilizadas são search, match, findall e sub.

import re

texto = "O pedido número 12345 foi enviado em 15/03/2025"

# search: encontra a primeira ocorrência em qualquer posição
resultado = re.search(r"\d+", texto)
if resultado:
    print(f"Primeiro número encontrado: {resultado.group()}")
    # Saída: Primeiro número encontrado: 12345

# findall: retorna todas as ocorrências
numeros = re.findall(r"\d+", texto)
print(f"Todos os números: {numeros}")
# Saída: Todos os números: ['12345', '15', '03', '2025']

# match: verifica se o padrão está no início da string
inicio = re.match(r"O pedido", texto)
print(f"Começa com 'O pedido': {inicio is not None}")
# Saída: Começa com 'O pedido': True

A diferença entre search e match é sutil mas importante: match só verifica o início da string, enquanto search procura em qualquer posição.

Caracteres especiais e metacaracteres

Os metacaracteres são o coração das expressões regulares. Cada um tem um significado específico que permite construir padrões complexos.

import re

# \d - dígito (0-9)
# \w - caractere alfanumérico (letras, dígitos, underscore)
# \s - espaço em branco (espaço, tab, quebra de linha)
# .  - qualquer caractere exceto quebra de linha
# ^  - início da string
# $  - final da string

exemplos = [
    (r"\d{3}\.\d{3}\.\d{3}-\d{2}", "CPF: 123.456.789-00"),
    (r"\(\d{2}\)\s\d{4,5}-\d{4}", "Telefone: (11) 98765-4321"),
    (r"[A-Z]{3}-\d{4}", "Placa antiga: ABC-1234"),
    (r"[A-Z]{3}\d[A-Z]\d{2}", "Placa Mercosul: ABC1D23"),
]

for padrao, texto in exemplos:
    resultado = re.search(padrao, texto)
    if resultado:
        print(f"Encontrado: {resultado.group()}")

Quantificadores

Os quantificadores definem quantas vezes um elemento pode se repetir:

import re

texto = "aab aaab ab aaaaab"

# * - zero ou mais vezes
print(re.findall(r"a*b", texto))
# ['aab', 'aaab', 'ab', 'aaaaab']

# + - uma ou mais vezes
print(re.findall(r"a+b", texto))
# ['aab', 'aaab', 'ab', 'aaaaab']

# ? - zero ou uma vez
print(re.findall(r"a?b", texto))
# ['ab', 'ab', 'ab', 'ab']

# {n,m} - entre n e m vezes
print(re.findall(r"a{2,3}b", texto))
# ['aab', 'aaab', 'aaab']

Grupos de captura

Grupos permitem extrair partes específicas de um texto. Eles são definidos com parênteses e são extremamente úteis na extração de dados estruturados.

import re

log = "2025-08-12 14:30:45 [ERROR] Conexão com banco de dados falhou"

padrao = r"(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2}) \[(\w+)\] (.+)"
resultado = re.search(padrao, log)

if resultado:
    data = resultado.group(1)
    hora = resultado.group(2)
    nivel = resultado.group(3)
    mensagem = resultado.group(4)
    print(f"Data: {data}")
    print(f"Hora: {hora}")
    print(f"Nível: {nivel}")
    print(f"Mensagem: {mensagem}")

Grupos nomeados

Grupos nomeados tornam o código ainda mais legível, especialmente quando há muitos grupos:

import re

email_texto = "Contato: joao.silva@empresa.com.br ou maria@gmail.com"

padrao = r"(?P<usuario>[\w.]+)@(?P<dominio>[\w.]+)"
resultados = re.finditer(padrao, email_texto)

for match in resultados:
    print(f"Usuário: {match.group('usuario')}")
    print(f"Domínio: {match.group('dominio')}")
    print("---")

Validação de dados

Uma das aplicações mais comuns de regex é a validação de entrada de dados. Veja exemplos práticos para o contexto brasileiro:

import re

def validar_cpf_formato(cpf):
    """Valida o formato do CPF (apenas formato, não o dígito verificador)."""
    padrao = r"^\d{3}\.\d{3}\.\d{3}-\d{2}$"
    return bool(re.match(padrao, cpf))

def validar_email(email):
    """Valida formato básico de e-mail."""
    padrao = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
    return bool(re.match(padrao, email))

def validar_cep(cep):
    """Valida formato de CEP brasileiro."""
    padrao = r"^\d{5}-?\d{3}$"
    return bool(re.match(padrao, cep))

def validar_telefone(telefone):
    """Valida telefone brasileiro com DDD."""
    padrao = r"^\(?\d{2}\)?\s?\d{4,5}-?\d{4}$"
    return bool(re.match(padrao, telefone))

# Testando as validações
testes = [
    ("CPF", validar_cpf_formato, "123.456.789-00"),
    ("Email", validar_email, "usuario@dominio.com.br"),
    ("CEP", validar_cep, "01310-100"),
    ("Telefone", validar_telefone, "(11) 98765-4321"),
]

for nome, funcao, valor in testes:
    resultado = "Válido" if funcao(valor) else "Inválido"
    print(f"{nome} '{valor}': {resultado}")

Substituição com re.sub

A função sub permite substituir padrões encontrados por novos textos, sendo ideal para limpeza e transformação de dados:

import re

# Removendo caracteres especiais
texto_sujo = "Preço: R$ 1.299,99!!! Compre já!!!"
texto_limpo = re.sub(r"[!]+", "", texto_sujo)
print(texto_limpo)
# Saída: Preço: R$ 1.299,99 Compre já

# Mascarando dados sensíveis
documento = "CPF do cliente: 123.456.789-00"
mascarado = re.sub(r"\d{3}\.\d{3}\.\d{3}-\d{2}", "***.***.***-**", documento)
print(mascarado)
# Saída: CPF do cliente: ***.***.***-**

# Usando função na substituição
def converter_para_maiuscula(match):
    return match.group().upper()

texto = "python é uma linguagem incrível"
resultado = re.sub(r"\b\w", converter_para_maiuscula, texto)
print(resultado)
# Saída: Python É Uma Linguagem Incrível

Compilando padrões para melhor desempenho

Quando um padrão é usado repetidamente, compilá-lo melhora o desempenho:

import re

# Compilando o padrão uma vez
padrao_data = re.compile(r"\d{2}/\d{2}/\d{4}")

textos = [
    "Nascimento: 15/03/1990",
    "Contratação: 01/07/2023",
    "Sem data aqui",
    "Vencimento: 30/12/2025",
]

for texto in textos:
    resultado = padrao_data.search(texto)
    if resultado:
        print(f"Data encontrada: {resultado.group()}")
    else:
        print(f"Nenhuma data em: {texto}")

Compilar padrões com re.compile() é uma boa prática em scripts que processam grandes volumes de dados ou chamam o mesmo padrão dentro de loops.

Boas práticas com expressões regulares

Para usar regex de forma eficiente e manutenível:

  • Use raw strings: sempre prefixe padrões com r para evitar problemas com caracteres de escape.
  • Comente padrões complexos: use o flag re.VERBOSE para adicionar comentários e espaços dentro do padrão.
  • Não exagere: para buscas simples, métodos de string como startswith(), endswith() e in são mais legíveis e rápidos.
  • Teste seus padrões: ferramentas online como regex101.com permitem testar e depurar expressões regulares interativamente.
  • Compile padrões reutilizáveis: se o mesmo padrão é usado múltiplas vezes, compile-o com re.compile().

Conclusão

Expressões regulares são uma ferramenta poderosa que todo programador Python deveria dominar. Com o módulo re, é possível validar dados, extrair informações e transformar textos de maneira eficiente e elegante. A chave para aprender regex é a prática constante — comece com padrões simples e vá aumentando a complexidade gradualmente.

Como próximos passos, experimente aplicar regex em projetos reais: processar logs de aplicação, limpar dados de formulários ou extrair informações de páginas web. A experiência prática é o que consolida o conhecimento.

E

Equipe Python Brasil

Contribuidor do Python Brasil — Aprenda Python em Português