PythonExpressões Regulares

Expressões Regulares

Expressões Regulares em Python: Guia Completo para Iniciantes

O que são Expressões Regulares?

Expressões Regulares (ou regex) são padrões usados para buscar, validar e manipular texto. Pense nelas como um "detetive" que procura por padrões específicos dentro de strings.

Imagine que você precisa:

  • Verificar se um email é válido
  • Encontrar todos os números de telefone em um texto
  • Extrair dados de um arquivo
  • Substituir partes específicas de um texto

Regex resolve tudo isso de forma elegante!

O Módulo re

Python tem um módulo nativo chamado re que trabalha com expressões regulares. Primeiro, você precisa importá-lo:

import re

Funções Principais

1. re.match() - Verifica no início da string

import re

texto = "Python é incrível"
padrao = r"Python"

resultado = re.match(padrao, texto)
if resultado:
    print("Encontrado:", resultado.group())
else:
    print("Não encontrado")

Importante: match() só verifica o início da string!

texto = "Eu amo Python"
resultado = re.match(r"Python", texto)  # Não encontra!
print(resultado)  # None

2. re.search() - Procura em qualquer lugar

texto = "Eu amo Python e JavaScript"
resultado = re.search(r"Python", texto)
if resultado:
    print("Encontrado em:", resultado.start(), "-", resultado.end())
    print("Trecho:", resultado.group())

3. re.findall() - Retorna todas as ocorrências

texto = "Telefones: 1199999999, 2188888888, 3177777777"
numeros = re.findall(r"\d{10}", texto)
print(numeros)  # ['1199999999', '2188888888', '3177777777']

4. re.sub() - Substitui padrões

texto = "Meu email é joao@gmail.com e maria@yahoo.com"
emails_ocultos = re.sub(r"\w+@\w+\.\w+", "[EMAIL OCULTO]", texto)
print(emails_ocultos)  # Meu email é [EMAIL OCULTO] e [EMAIL OCULTO]

Metacaracteres Básicos

. (ponto) - Qualquer caractere (exceto quebra de linha)

texto = "gato, gote, guta"
print(re.findall(r"g.t.", texto))  # ['gato', 'gote', 'guta']

* - Zero ou mais ocorrências

texto = "go, goo, gooo, gato"
print(re.findall(r"go*", texto))  # ['go', 'goo', 'gooo', 'g']

+ - Uma ou mais ocorrências

texto = "go, goo, gooo, gato"
print(re.findall(r"go+", texto))  # ['go', 'goo', 'gooo']

? - Zero ou uma ocorrência

texto = "cor, corr, corrr, corrrr"
print(re.findall(r"corr?", texto))  # ['cor', 'corr', 'corr']

[] - Conjunto de caracteres

texto = "casa, caso, casu, casã"
print(re.findall(r"cas[aeiou]", texto))  # ['casa', 'caso', 'casu']

^ - Início da string (quando usado fora de [])

texto = "Python é legal"
print(re.findall(r"^Python", texto))  # ['Python']

$ - Final da string

texto = "legal Python"
print(re.findall(r"Python$", texto))  # ['Python']

Grupos com ()

Grupos permitem capturar partes específicas do padrão:

texto = "João tem 25 anos e Maria tem 30 anos"
padrao = r"(\w+) tem (\d+) anos"
resultados = re.findall(padrao, texto)
print(resultados)  # [('João', '25'), ('Maria', '30')]

# Acessando grupos específicos
for nome, idade in resultados:
    print(f"{nome} tem {idade} anos")

Exemplos Práticos

1. Validar Email

import re

def validar_email(email):
    padrao = r"^[\w\.-]+@[\w\.-]+\.\w{2,}$"
    if re.match(padrao, email):
        return True
    return False

# Testes
emails = ["joao@gmail.com", "maria@yahoo", "teste@.com", "ana@empresa.com.br"]
for email in emails:
    print(f"{email}: {validar_email(email)}")

2. Validar CPF

import re

def validar_cpf(cpf):
    # Remove caracteres não numéricos
    cpf = re.sub(r"\D", "", cpf)
    
    # Verifica se tem 11 dígitos
    padrao = r"^\d{11}$"
    if not re.match(padrao, cpf):
        return False
    
    # Verifica se todos os dígitos são iguais (CPF inválido)
    if cpf == cpf[0] * 11:
        return False
    
    # Validação dos dígitos verificadores (simplificada)
    # (Em produção, implemente a validação completa)
    return True

cpfs = ["123.456.789-09", "111.111.111-11", "529.982.247-25"]
for cpf in cpfs:
    print(f"{cpf}: {validar_cpf(cpf)}")

3. Validar Telefone

import re

def validar_telefone(telefone):
    # Aceita formatos: (11) 99999-9999, 11999999999, 11 99999-9999
    padrao = r"^\(?\d{2}\)?\s?\d{4,5}-?\d{4}$"
    if re.match(padrao, telefone):
        return True
    return False

telefones = ["(11) 99999-9999", "11999999999", "11 9999-9999", "12345"]
for tel in telefones:
    print(f"{tel}: {validar_telefone(tel)}")

4. Extrair Dados de um Texto

import re

texto = """
Cliente: João Silva
Email: joao.silva@email.com
Telefone: (11) 98765-4321
CPF: 123.456.789-09
Data de nascimento: 15/03/1990
"""

# Extrair email
email = re.search(r"[\w\.-]+@[\w\.-]+\.\w+", texto)
print("Email:", email.group())

# Extrair telefone
telefone = re.search(r"\(?\d{2}\)?\s?\d{4,5}-?\d{4}", texto)
print("Telefone:", telefone.group())

# Extrair CPF
cpf = re.search(r"\d{3}\.\d{3}\.\d{3}-\d{2}", texto)
print("CPF:", cpf.group())

# Extrair data
data = re.search(r"\d{2}/\d{2}/\d{4}", texto)
print("Data:", data.group())

Dicas Importantes

1. Use r"" para raw strings

# Sem raw string, \n é interpretado como quebra de linha
padrao_errado = "\n"  # Quebra de linha

# Com raw string, \n é literal
padrao_certo = r"\n"  # Literalmente "\n"

2. Escape de caracteres especiais

# Para buscar um ponto literal, use \.
texto = "Preço: R$ 10.50"
print(re.findall(r"\d+\.\d+", texto))  # ['10.50']

3. Use re.IGNORECASE para ignorar maiúsculas/minúsculas

texto = "Python, PYTHON, python"
print(re.findall(r"python", texto, re.IGNORECASE))  # ['Python', 'PYTHON', 'python']

Erros Comuns

1. Esquecer de escapar pontos

# ERRADO
texto = "email@exemplo.com"
print(re.findall(r"email@exemplo.com", texto))  # None (ponto captura qualquer caractere)

# CERTO
print(re.findall(r"email@exemplo\.com", texto))  # ['email@exemplo.com']

2. Usar match quando deveria usar search

texto = "O email é joao@gmail.com"
# ERRADO: match procura no início
resultado = re.match(r"joao@gmail.com", texto)  # None

# CERTO: search procura em qualquer lugar
resultado = re.search(r"joao@gmail.com", texto)  # Encontra!

3. Não usar raw strings

# ERRADO
padrao = "\d"  # \d é interpretado como caractere de controle

# CERTO
padrao = r"\d"  # \d é literal

Exercício Prático

Crie um programa que valide senhas com os seguintes critérios:

  • Mínimo 8 caracteres
  • Pelo menos uma letra maiúscula
  • Pelo menos uma letra minúscula
  • Pelo menos um número
  • Pelo menos um caractere especial (@, #, $, %, &)
import re

def validar_senha(senha):
    if len(senha) < 8:
        return "Senha muito curta (mínimo 8 caracteres)"
    
    if not re.search(r"[A-Z]", senha):
        return "Senha precisa ter pelo menos uma letra maiúscula"
    
    if not re.search(r"[a-z]", senha):
        return "Senha precisa ter pelo menos uma letra minúscula"
    
    if not re.search(r"\d", senha):
        return "Senha precisa ter pelo menos um número"
    
    if not re.search(r"[@#$%&]", senha):
        return "Senha precisa ter pelo menos um caractere especial (@, #, $, %, &)"
    
    return "Senha válida!"

# Testes
senhas = ["abc123", "Senha123", "Senha@123", "senha@123", "SENHA@123"]
for senha in senhas:
    print(f"{senha}: {validar_senha(senha)}")

Conclusão

Expressões regulares são ferramentas poderosas para manipulação de texto. Comece com padrões simples e vá aumentando a complexidade aos poucos. Use sites como regex101.com para testar seus padrões visualmente.

Lembre-se: regex é como um superpoder - quando você aprende, nunca mais vai querer viver sem!