Quando recorrer a regex
Expressões regulares são uma pequena linguagem para descrever padrões de texto. São poderosas e são fáceis de superutilizar.
Antes de recorrer a re, pergunte se métodos de string simples resolveriam. .split(), .replace(), .startswith(), "target" in text — são mais rápidos, mais legíveis e menos propensos a erro do que o regex equivalente. Guarde regex para quando o padrão que te interessa é genuinamente estruturado mas flexível demais para operações fixas de string: endereços de email, números de telefone, linhas de log com formato conhecido, snippets de HTML ou Markdown, qualquer busca de "encontre esse tipo de coisa".
O vocabulário básico
Um padrão regex é uma string que descreve o que você está procurando. Alguns blocos:
.— qualquer caractere único\d— qualquer dígito (0–9)\w— qualquer caractere de "palavra" (letra, dígito, underscore)\s— qualquer caractere de espaço^— início da string$— fim da string[abc]— qualquer um entre a, b ou c[^abc]— qualquer caractere exceto a, b, ca|b— a ou b*— zero ou mais do anterior+— um ou mais?— zero ou um{3}— exatamente 3{2,5}— entre 2 e 5( ... )— grupo (captura o match interno)
Isso basta para a maioria dos regex do mundo real.
As funções-chave
re.search(pattern, text) encontra o primeiro match em qualquer lugar da string. Retorna um objeto de match ou None:
Sempre use raw string (r"...") para padrões regex. Senão o Python tenta interpretar as barras invertidas como escapes de string e você acaba com um padrão diferente do que digitou.
re.match(pattern, text) é como search mas só bate no começo:
Na maior parte do tempo você quer search.
re.findall(pattern, text) retorna todos os matches não sobrepostos como lista:
Repare que findall retorna strings, não objetos de match. Se você tem um padrão com um grupo, recebe o conteúdo do grupo. Com vários grupos, recebe uma lista de tuplas.
Grupos de captura
Parênteses num padrão capturam o que bateu lá dentro:
Grupos nomeados geralmente são mais claros:
Quando o regex tem mais de um grupo, dar nome torna o código de extração muito mais fácil de acompanhar.
Substituindo com re.sub
re.sub(pattern, replacement, text) substitui todo match:
Isso remove tudo que não é dígito. A substituição pode referenciar grupos capturados com \1, \2, etc. — ou em raw strings, \g<1> é mais claro:
Você também pode passar uma função como substituição. Isso é útil para transformações que não são troca simples:
Compilando padrões para reuso
Se você está usando o mesmo padrão muitas vezes — principalmente num laço — compile uma vez:
Padrões compilados expõem os mesmos métodos — search, match, findall, sub — sem o padrão como primeiro argumento. Levemente mais eficiente, muitas vezes mais legível.
Flags
Modificadores comuns, passados como argumento flags= ou combinados com OR:
re.IGNORECASE(re.I) — match sem diferenciar maiúsculas.re.MULTILINE(re.M) —^e$batem em cada linha, não só nos limites da string.re.DOTALL(re.S) —.também bate em quebras de linha (por padrão não).re.VERBOSE(re.X) — permite espaço em branco e comentários#no padrão, para legibilidade.
re.VERBOSE é especialmente útil para padrões complexos:
Regex multilinha e com comentários são muito mais fáceis de manter do que one-liners opacos.
Guloso vs preguiçoso
Quantificadores (*, +, ?, {n,}) são gulosos por padrão — batem o quanto conseguem. Adicione um ? para torná-los preguiçosos:
A versão gulosa captura a substring toda de <b> até </i> — provavelmente não o que você queria. O .+? preguiçoso para no primeiro >.
(Nota lateral: não parseie HTML de verdade com regex em produção. Use html.parser ou BeautifulSoup. O exemplo acima é só para ilustrar gulosidade.)
Um exemplo realista
Parsear linhas de um formato simples de log:
Muito poder em poucas linhas.
Alguns hábitos
- Sempre use raw strings para padrões.
- Comece com o padrão mais simples que funciona; aperte depois.
- Use grupos nomeados quando tiver mais de um grupo.
- Compile padrões que vai reusar.
- Regex é mais lento do que métodos simples de string. Se
.split()resolve, use.split().
Próxima: erros e debugging
Isso encerra o tour de dados do mundo real — arquivos, JSON, CSV, HTTP, datas e regex. Qualquer coisa num programa de verdade cedo ou tarde bate num erro, porém, e ler tracebacks Python bem é a maior habilidade de debug que você pode adquirir. O último capítulo cobre exceções e os erros específicos que você mais vai encontrar.
Perguntas frequentes
O que é regex em Python?
Uma expressão regular (regex) é uma pequena linguagem para descrever padrões em texto. O módulo re do Python permite buscar padrões, extrair pedaços e substituir matches. É exagero para operações de string simples — use métodos de string como .split() ou .replace() primeiro — mas imbatível para pattern matching estruturado.
Qual a diferença entre re.match e re.search?
re.match só bate no começo da string. re.search varre a string toda e encontra o primeiro match em qualquer lugar. Na dúvida, use search — bate melhor com a intuição humana.
Sempre devo usar raw strings para padrões regex?
Sim. Padrões regex muitas vezes contêm barras invertidas (\d, \s, \b), que strings Python interpretam como sequências de escape. Prefixar com r — r'\d+' — diz ao Python para pegar a string literalmente, o que mantém o regex legível.