glob.translate: converta padrões glob em regex

Publicado em: 24/09/2026
Tempo de leitura: 5 minutos
Código e estrutura de arquivos para filtros com glob.translate no Python

O módulo glob é conhecido por localizar arquivos usando padrões como *.py, dados/**/*.csv e relatorio-??.pdf. Em versões recentes do Python, a função glob.translate() permite transformar um padrão glob em uma expressão regular. Isso é útil quando você quer reaproveitar a sintaxe simples dos globs, mas precisa aplicar a correspondência em textos, caminhos virtuais, listas vindas de uma API ou estruturas que não estão diretamente no sistema de arquivos.

Neste guia, você vai entender como glob.translate funciona, quais diferenças existem em relação a fnmatch.translate, como lidar com diretórios recursivos, separadores de caminho, arquivos ocultos e validação segura de padrões.

O que é glob.translate

glob.translate(pattern) recebe um padrão glob e devolve uma string de expressão regular compatível com o módulo re. O resultado pode ser compilado com re.compile() e usado várias vezes. Isso evita reimplementar manualmente regras de *, ?, classes de caracteres e caminhos recursivos.

import glob
import re

regex = re.compile(glob.translate("src/**/*.py", recursive=True))

caminhos = [
    "src/app.py",
    "src/api/routes.py",
    "tests/test_app.py",
]

selecionados = [c for c in caminhos if regex.match(c)]
print(selecionados)

O padrão é interpretado como caminho, não como texto genérico. Por isso, o separador de diretórios tem importância e o caractere * normalmente não atravessa separadores.

Diferença entre glob e regex

Globs foram criados para serem simples. O asterisco representa uma sequência de caracteres, a interrogação representa um caractere e colchetes representam classes. Expressões regulares são muito mais poderosas, mas também mais difíceis de ler e mais propensas a erros. glob.translate cria uma ponte entre as duas abordagens.

Use glob quando usuários ou arquivos de configuração precisam fornecer filtros legíveis. Converta para regex quando você precisa aplicar o filtro repetidamente, combinar com outras validações ou usar dados que não estão em disco.

Correspondência recursiva com dois asteriscos

Quando recursive=True, o padrão ** pode representar vários níveis de diretório. Isso permite selecionar arquivos em árvores profundas.

pattern = "projeto/**/test_*.py"
regex = re.compile(glob.translate(pattern, recursive=True))

for caminho in caminhos:
    if regex.match(caminho):
        print(caminho)

Sem recursive=True, o comportamento de ** não deve ser tratado como travessia arbitrária de diretórios. Ao aceitar padrões de usuários, defina explicitamente essa opção para evitar resultados inesperados.

Arquivos e diretórios ocultos

Em sistemas Unix, nomes iniciados por ponto são tratados como ocultos. A opção include_hidden controla se curingas podem corresponder a esses componentes. Essa distinção é importante em ferramentas de backup, indexadores e analisadores de projetos, porque pastas como .git, .venv e .cache podem aumentar muito o volume processado.

regex = re.compile(
    glob.translate("**/*.toml", recursive=True, include_hidden=False)
)

Mesmo quando você trabalha apenas com listas de strings, essa regra continua útil para reproduzir o comportamento esperado do módulo glob.

Separadores personalizados

A função pode aceitar separadores específicos. Isso é interessante quando os caminhos vêm de um arquivo ZIP, de uma API, de um banco de dados ou de um sistema remoto. Em arquivos ZIP, por exemplo, a barra normal costuma ser usada mesmo no Windows.

regex = re.compile(
    glob.translate("assets/**/*.png", recursive=True, seps="/")
)

Ao fixar o separador, você torna o filtro previsível entre plataformas. Essa prática também facilita testes automatizados.

glob.translate versus fnmatch.translate

fnmatch.translate converte padrões voltados a nomes, enquanto glob.translate entende segmentos de caminho. Em um glob de caminhos, o separador possui significado especial. Já o fnmatch costuma tratar o texto como uma sequência única.

Se o seu filtro é apenas para nomes como foto-*.jpg, fnmatch pode ser suficiente. Para padrões com diretórios, recursão e controle de arquivos ocultos, glob.translate é mais apropriado.

Compile a regex uma única vez

Quando o mesmo padrão será aplicado a milhares de itens, compile a expressão regular uma vez. Isso reduz trabalho repetido e deixa o código mais claro.

def criar_filtro(pattern, *, recursive=False):
    expressao = glob.translate(pattern, recursive=recursive)
    return re.compile(expressao)

filtro = criar_filtro("logs/**/*.json", recursive=True)
resultados = [p for p in caminhos if filtro.match(p)]

Se os padrões mudam dinamicamente, você pode manter um cache pequeno. Porém, limite a quantidade de padrões aceitos para evitar consumo de memória desnecessário.

Validação e segurança

Padrões glob não executam código, mas ainda podem causar problemas de desempenho. Um padrão muito amplo pode selecionar milhões de caminhos. Em aplicações web, não use diretamente um padrão recebido do usuário para percorrer todo o servidor. Restrinja a raiz, limite profundidade, tamanho do padrão e quantidade de resultados.

Ao trabalhar apenas com strings, o risco de acesso ao sistema de arquivos diminui, mas ainda existe a possibilidade de processamento excessivo. Defina limites e rejeite padrões anormalmente longos.

Exemplo com caminhos vindos de uma API

Imagine uma API que retorna chaves de objetos armazenados em nuvem. Você quer filtrar apenas imagens dentro da pasta de um projeto.

objetos = [
    "clientes/acme/logo.png",
    "clientes/acme/docs/manual.pdf",
    "clientes/acme/screens/home.webp",
    "clientes/outro/logo.png",
]

padrao = "clientes/acme/**/*.[pw][ne][gb]"
regex = re.compile(glob.translate(padrao, recursive=True, seps="/"))

filtrados = [item for item in objetos if regex.match(item)]

Para extensões variadas, muitas vezes é mais legível combinar vários filtros ou verificar o sufixo com pathlib. Não force um único padrão a resolver toda a lógica.

Integração com pathlib

pathlib oferece uma API orientada a objetos para caminhos. Você pode normalizar dados com PurePosixPath antes de aplicar o regex.

from pathlib import PurePosixPath

normalizados = [PurePosixPath(p).as_posix() for p in objetos]
filtrados = [p for p in normalizados if regex.match(p)]

Essa combinação é útil em aplicações multiplataforma. Veja também nosso conteúdo sobre pathlib no Python, o guia de expressões regulares, o artigo sobre módulo os e o tutorial de arquivos grandes.

Testes recomendados

Crie testes para caminhos na raiz, caminhos profundos, nomes ocultos, separadores diferentes e strings que quase correspondem. Também teste padrões vazios, extensões em maiúsculas e caminhos com espaços.

casos = {
    "src/main.py": True,
    "src/api/main.py": True,
    "src/.cache/main.py": False,
    "tests/main.py": False,
}

filtro = re.compile(glob.translate("src/**/*.py", recursive=True))
for caminho, esperado in casos.items():
    assert bool(filtro.match(caminho)) is esperado

Quando usar

Use glob.translate quando você precisa oferecer uma sintaxe de filtro simples e aplicar o resultado fora do sistema de arquivos. Ele funciona bem em indexadores, backups, ferramentas de build, listas de objetos em nuvem, manifestos e arquivos compactados.

Para consultar detalhes oficiais, veja a documentação do módulo glob e a documentação do módulo re. A principal recomendação é manter os padrões pequenos, previsíveis e acompanhados por testes.

Conclusão

glob.translate permite combinar a legibilidade dos padrões glob com a flexibilidade das expressões regulares. Ao entender recursão, separadores, arquivos ocultos e compilação, você consegue criar filtros portáveis e eficientes. Em projetos reais, valide padrões recebidos, limite o escopo e teste casos de borda para evitar correspondências inesperadas.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Código Python com anotações e type hints em um notebook
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    annotationlib: resolva anotações adiadas no Python

    Aprenda annotationlib no Python para recuperar anotações, lidar com referências futuras e evitar avaliação insegura.

    Ler mais

    Tempo de leitura: 8 minutos
    24/09/2026
    Pessoa programando em Python com banco SQLite e dbm.sqlite3
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    dbm.sqlite3: chave-valor com SQLite no Python

    Aprenda a usar dbm.sqlite3 no Python para armazenar pares chave-valor com SQLite, controlar compatibilidade, desempenho e concorrência.

    Ler mais

    Tempo de leitura: 7 minutos
    23/09/2026
    Desenvolvedor trabalhando com tarefas assíncronas e TaskGroup eager_start no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    TaskGroup eager_start: controle o início de tarefas

    Aprenda a usar eager_start em asyncio.TaskGroup para controlar o início de tarefas, entender a execução imediata e evitar surpresas em

    Ler mais

    Tempo de leitura: 7 minutos
    23/09/2026
    Desenvolvedora trabalhando com tipagem estática e typing.ReadOnly no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    typing.ReadOnly: campos imutáveis em TypedDict

    Aprenda typing.ReadOnly no Python para declarar chaves somente leitura em TypedDict e criar contratos de dados mais seguros.

    Ler mais

    Tempo de leitura: 6 minutos
    22/09/2026
    Código Python representando argumentos posicionais com functools.Placeholder
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    functools.Placeholder: argumentos no meio do partial

    Aprenda functools.Placeholder no Python para reservar argumentos intermediários em partial e criar callbacks e adaptadores mais claros.

    Ler mais

    Tempo de leitura: 6 minutos
    22/09/2026
    Código Python com aviso de API obsoleta usando warnings.deprecated
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    warnings.deprecated: marque APIs obsoletas

    Aprenda warnings.deprecated no Python para marcar APIs obsoletas, orientar migrações e integrar avisos com tipagem, testes e CI.

    Ler mais

    Tempo de leitura: 7 minutos
    21/09/2026