Domine Expressões Regulares com o Módulo `re` do Python! Um Guia Completo para Busca e Substituição de Strings
Para executar Python no prompt de comando ou PowerShell no seu PC, é necessário baixar e instalar o Python.
Se ainda não o fez, consulte o artigo Instalação do Python e configuração do ambiente de desenvolvimento para instalar o Python.
Ao criar sites ou processar dados, você frequentemente se depara com situações como "Quero extrair apenas strings com um padrão específico deste texto!" ou "Quero formatar dados com formatos variados de uma só vez!". É nessas horas que as "expressões regulares" mostram seu poder imenso. Parece difícil? Que nada! Com o módulo `re` do Python, até mesmo iniciantes podem se tornar mestres na manipulação de strings de forma surpreendentemente fácil!
Neste artigo, vamos explicar desde o básico até as aplicações de expressões regulares usando o módulo `re` do Python, de uma maneira super fácil de entender e com muitos exemplos de código prontos para copiar e colar. Primeiro, tente rodar o código para ter a experiência de "Ah, é assim que se usa!". Vamos mergulhar juntos no mundo das expressões regulares!
Afinal, o que são Expressões Regulares e o módulo `re`?
Uma expressão regular é, em poucas palavras, "uma string especial para representar padrões em texto". É como uma linguagem comum para buscar e substituir strings com condições ambíguas, como "uma sequência de três números" ou "algo no formato de um endereço de e-mail".
E a funcionalidade padrão (biblioteca) para lidar com essas expressões regulares em Python é o módulo `re`. Apenas importando o módulo `re`, você pode realizar processamentos complexos de strings com apenas algumas linhas de código.
Primeiro o Básico! 4 Funções para 'Encontrar' Strings
O módulo `re` possui várias funções para buscar strings, mas vamos primeiro dominar as quatro mais usadas. Essas funções recebem como argumentos um "padrão de expressão regular" и uma "string alvo da busca".
1. `re.search()` - Retorna a primeira correspondência encontrada
`re.search()` varre a string inteira e retorna informações sobre a primeira parte que corresponde ao padrão. Ele retorna `None` se nenhuma correspondência for encontrada. É a função de busca mais comum e fácil de usar.
Por exemplo, vamos tentar encontrar a palavra "Python" em uma frase.
<?php
import re
text = "Hello, this is a pen. I love Python programming!"
pattern = "Python"
# Procura o padrão dentro da string
match = re.search(pattern, text)
if match:
print(f"Encontrado!: '{match.group()}'")
print(f"Índice inicial: {match.start()}, Índice final: {match.end()}")
else:
print("Não encontrado.")
# Resultado da Execução:
# Encontrado!: 'Python'
# Índice inicial: 31, Índice final: 37
?>
2. `re.match()` - Verifica se o "início" da string corresponde
`re.match()` é semelhante a `re.search()`, mas com uma grande diferença: ele verifica apenas se o padrão corresponde desde o início da string. Padrões no meio da string são ignorados.
Vamos usar `re.match()` na frase anterior. Ele encontrará correspondência para "Hello", mas não para "Python".
<?php
import re
text = "Hello, this is a pen. I love Python programming!"
# Padrão 1: "Hello" (no início da string)
match1 = re.match("Hello", text)
if match1:
print(f"Resultado da busca por 'Hello': Correspondeu! -> {match1.group()}")
else:
print("Resultado da busca por 'Hello': Não correspondeu.")
# Padrão 2: "Python" (no meio da string)
match2 = re.match("Python", text)
if match2:
print(f"Resultado da busca por 'Python': Correspondeu! -> {match2.group()}")
else:
print("Resultado da busca por 'Python': Não correspondeu.")
# Resultado da Execução:
# Resultado da busca por 'Hello': Correspondeu! -> Hello
# Resultado da busca por 'Python': Não correspondeu.
?>
3. `re.findall()` - Retorna "todas" as correspondências em uma lista
`re.findall()` encontra todas as partes que correspondem ao padrão e as retorna como uma lista de strings. É extremamente útil para quando você quer extrair todos os números de uma frase, por exemplo.
Aqui, vamos usar o padrão de regex `\d+`. Isso significa "uma sequência de um ou mais dígitos".
<?php
import re
text = "O item A custa 100 por 1 unidade, e o item B custa 250 por 3 unidades. O número do pedido é 8801."
# \d+ é um padrão de regex que significa 'um ou mais dígitos consecutivos'
pattern = r"\d+"
# Obtém todas as partes correspondentes como uma lista
numbers = re.findall(pattern, text)
print(f"Lista de números encontrados: {numbers}")
# Resultado da Execução:
# Lista de números encontrados: ['1', '100', '3', '250', '8801']
?>
※ O `r` antes do padrão de regex significa "string crua" (raw string), que impede que a barra invertida `\` seja tratada como um caractere de escape. É uma boa prática usá-lo ao escrever expressões regulares para evitar erros desnecessários.
4. `re.finditer()` - Retorna todas as correspondências como um "iterador"
`re.finditer()` é semelhante a `re.findall()`, mas difere por retornar os resultados como um "iterador" em vez de uma lista. Um iterador é adequado para processar elementos um a um, como em um laço `for`.
É útil quando você quer não apenas a string correspondente, mas também o objeto de correspondência (que contém informações como a posição inicial) que `search` ou `match` retornariam.
<?php
import re
text = "Meu aniversário é em 31 de dezembro de 1995, e o aniversário dele é em 5 de maio de 2003."
# Encontra números de 4 dígitos
pattern = r"\d{4}"
# Obtém as correspondências como um iterador
matches = re.finditer(pattern, text)
print("Anos encontrados:")
for m in matches:
print(f"- {m.group()} (posição: {m.start()}-{m.end()})")
# Resultado da Execução:
# Anos encontrados:
# - 1995 (posição: 29-33)
# - 2003 (posição: 71-75)
?>
"Substitua" Strings Livremente - re.sub()
Outra característica poderosa das expressões regulares é a "substituição". Com `re.sub()`, você pode substituir em massa as partes que correspondem a um padrão por outra string.
Por exemplo, vamos substituir números de telefone em um texto pela string "(confidencial)" para privacidade. Usaremos a regex `\d{2,4}-\d{2,4}-\d{4}`, que corresponde a formatos de número de telefone como 080-1234-5678.
<?php
import re
text = "Para dúvidas, contate o suporte Sato (080-1111-2222). Ou contate o representante de vendas Suzuki (03-3333-4444)."
# Regex para corresponder a números de telefone
pattern = r"\d{2,4}-\d{2,4}-\d{4}"
replacement = "(confidencial)"
# Substitui as partes que correspondem ao padrão
new_text = re.sub(pattern, replacement, text)
print(new_text)
# Resultado da Execução:
# Para dúvidas, contate o suporte Sato ((confidencial)). Ou contate o representante de vendas Suzuki ((confidencial)).
?>
Avançado: Substituindo com Grupos
O verdadeiro poder do `re.sub()` é liberado quando combinado com o recurso de "grupos" das expressões regulares. Ao envolver partes do padrão em `()`, você pode reutilizar essas partes (grupos) na string de substituição.
Por exemplo, vamos trocar nomes que estão na ordem "Sobrenome-Nome" para a ordem "Nome Sobrenome".
<?php
import re
text = "Personagens: Tanjiro-Kamado, Zenitsu-Agatsuma, Inosuke-Hashibira"
# (\w+) é um grupo. O primeiro corresponde ao sobrenome, o segundo ao nome.
pattern = r"(\w+)-(\w+)"
# \2 refere-se ao segundo grupo (nome), \1 refere-se ao primeiro grupo (sobrenome)
replacement = r"\2 \1"
new_text = re.sub(pattern, replacement, text)
print(new_text)
# Resultado da Execução:
# Personagens: Kamado Tanjiro, Agatsuma Zenitsu, Hashibira Inosuke
?>
【Teste ao Vivo】Vamos Construir um Verificador de Regex!
Usando o conhecimento que adquirimos até agora, vamos construir um "Verificador de Regex" que permite checar o comportamento de expressões regulares em tempo real no seu navegador!
Copie todo o código HTML abaixo, salve-o em um arquivo com um nome como `verificador.html` e abra-o no seu navegador. Insira seu texto na área de texto, o padrão desejado (ex: `\d+` ou `[A-Za-z]+`) no campo de entrada de regex e pressione o botão "Executar Destaque". As partes correspondentes serão destacadas em azul claro. Este é um exemplo perfeito para experimentar o código funcionando ao vivo!
<!DOCTYPE html>
<html lang="pt">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Verificador de Expressões Regulares com Destaque</title>
<style>
body {
background-color: #202124;
color: #e8eaed;
font-family: sans-serif;
line-height: 1.6;
padding: 20px;
}
.container {
max-width: 800px;
margin: 0 auto;
}
h1 {
color: #669df6;
border-bottom: 1px solid #5f6368;
padding-bottom: 10px;
}
textarea, input[type="text"] {
width: 100%;
padding: 10px;
margin-bottom: 10px;
background-color: #3c4043;
color: #e8eaed;
border: 1px solid #5f6368;
border-radius: 4px;
box-sizing: border-box; /* Inclui o padding no cálculo da largura */
}
button {
padding: 10px 20px;
background-color: #8ab4f8;
color: #202124;
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
}
button:hover {
opacity: 0.9;
}
#result {
margin-top: 20px;
padding: 15px;
border: 1px solid #5f6368;
border-radius: 4px;
white-space: pre-wrap; /* Exibe as quebras de linha como estão */
word-wrap: break-word; /* Quebra palavras longas */
}
.highlight {
background-color: #3367d6; /* Destaque com azul claro */
color: #ffffff;
border-radius: 3px;
padding: 0 2px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
</style>
</head>
<body>
<div class="container">
<h1>Verificador de Expressões Regulares com Destaque</h1>
<label for="text-input">Texto para testar:</label>
<textarea id="text-input" rows="8">Python 3.10 é a versão mais recente. Meu email é sample-user@example.com. Por favor, me ligue no 090-1234-5678. O evento é em 26/07/2025.</textarea>
<label for="regex-input">Padrão da Expressão Regular:</label>
<input type="text" id="regex-input" value="\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b">
<button onclick="highlightMatches()">Executar Destaque</button>
<label for="result" style="margin-top: 20px;">Resultado:</label>
<div id="result"></div>
</div>
<script>
function highlightMatches() {
const text = document.getElementById('text-input').value;
const regexPattern = document.getElementById('regex-input').value;
const resultDiv = document.getElementById('result');
if (!text || !regexPattern) {
resultDiv.textContent = 'Por favor, insira o texto e o padrão da expressão regular.';
return;
}
try {
// Adiciona a flag g (busca global) e i (ignora maiúsculas/minúsculas)
const regex = new RegExp(regexPattern, 'gi');
const highlightedText = text.replace(regex, (match) => {
return `<span class="highlight">${match}</span>`;
});
resultDiv.innerHTML = highlightedText;
} catch (e) {
resultDiv.textContent = 'Padrão de expressão regular inválido: ' + e.message;
}
}
// Executar também no carregamento inicial
document.addEventListener('DOMContentLoaded', highlightMatches);
</script>
</body>
</html>
Dicas e Truques para se Destacar!
Finalmente, vamos cobrir algumas técnicas para usar expressões regulares de forma mais eficaz e as armadilhas comuns nas quais os iniciantes costumam cair.
Correspondência Gulosa (Greedy) vs. Não Gulosa (Non-Greedy)
Por padrão, quantificadores de regex como `*` e `+` se comportam de maneira "Gulosa" (Greedy). Isso significa que eles tentam corresponder à string mais longa possível.
Por exemplo, suponha que você queira extrair apenas o conteúdo entre `<p>` e `</p>`. O que acontece se você usar o padrão `<.*>` em uma string como `<p>primeiro parágrafo</p><p>segundo parágrafo</p>`?
<?php
import re
html = "<p>primeiro parágrafo</p><p>segundo parágrafo</p>"
# Correspondência Gulosa (Greedy)
greedy_match = re.search(r"<.*>", html)
print(f"Correspondência gulosa: {greedy_match.group()}")
# Correspondência Não Gulosa (Non-Greedy): adicione ? após *
non_greedy_match = re.search(r"<.*?>", html)
print(f"Correspondência não gulosa: {non_greedy_match.group()}")
# Resultado da Execução:
# Correspondência gulosa: <p>primeiro parágrafo</p><p>segundo parágrafo</p>
# Correspondência não gulosa: <p>
?>
Com a correspondência gulosa, ele capturou tudo desde o primeiro `<` até o último `>`. Por outro lado, `*?`, que tem um `?` após o `*`, é "Não Guloso", o que significa que ele tenta corresponder à string mais curta possível. Isso permite que a correspondência termine assim que o primeiro `>` for encontrado. Essa diferença é crucial ao analisar HTML ou XML.
Melhore o Desempenho com `re.compile()`
Se você usa o mesmo padrão de expressão regular repetidamente em seu programa, é recomendável "compilar" o padrão antecipadamente usando `re.compile()`.
Isso poupa o Python do esforço de analisar o padrão a cada vez, melhorando a velocidade de processamento. O objeto de padrão compilado possui métodos como `search()` e `findall()`.
<?php
import re
# Compila o padrão de endereço de e-mail
email_pattern = re.compile(r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}")
# Busca usando o objeto compilado
text1 = "O contato é a@b.com."
match1 = email_pattern.search(text1)
if match1:
print(f"Encontrado no Texto1: {match1.group()}")
text2 = "O suporte é support@example.co.jp."
match2 = email_pattern.search(text2)
if match2:
print(f"Encontrado no Texto2: {match2.group()}")
# Resultado da Execução:
# Encontrado no Texto1: a@b.com
# Encontrado no Texto2: support@example.co.jp
?>
Também tem o benefício de organizar seu código e torná-lo mais legível.
Resumo
Neste artigo, introduzimos o básico de expressões regulares usando o módulo `re` do Python. Pode parecer um pouco complicado no início, mas uma vez que você descobre seu poder, não conseguirá mais imaginar o processamento de texto sem expressões regulares.
- `re.search()`: Encontra a primeira ocorrência de um padrão em uma string.
- `re.match()`: Verifica se o início de uma string corresponde a um padrão.
- `re.findall()`: Obtém todas as ocorrências de um padrão como uma lista.
- `re.sub()`: Substitui partes de uma string que correspondem a um padrão.
Combinando esses fundamentos e dominando os metacaracteres, suas habilidades de processamento de dados melhorarão drasticamente. Sinta-se à vontade para copiar e colar o código deste artigo e experimentar vários padrões para se familiarizar com as expressões regulares!
Próximos Passos
Agora que você pode manipular dados de texto livremente com expressões regulares, por que не tentar operações com arquivos? Arquivos CSV, em particular, são um formato importante usado em muitas aplicações web e análise de dados. Domine como ler e escrever arquivos CSV usando o módulo `csv` do Python no seguinte artigo.