glob.translate: convierte patrones glob a regex

Publicado el: 24/09/2026
Tempo de leitura: 5 minutos
Código y estructura de archivos para filtros con glob.translate en Python

El módulo glob suele utilizarse para localizar archivos mediante patrones como *.py, datos/**/*.csv o informe-??.pdf. La función glob.translate() permite transformar un patrón glob en una expresión regular. Esto resulta útil cuando deseas conservar la sintaxis sencilla de los globs, pero necesitas filtrar rutas procedentes de una API, un archivo comprimido, una base de datos, un almacenamiento en la nube o una colección en memoria.

En esta guía aprenderás cómo funciona glob.translate, en qué se diferencia de fnmatch.translate, cómo tratar búsquedas recursivas, archivos ocultos, separadores de rutas y validación segura.

Qué hace glob.translate

glob.translate(pattern) devuelve una cadena de expresión regular compatible con el módulo re. Esa expresión puede compilarse una sola vez y reutilizarse para comparar muchas rutas.

import glob
import re

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

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

seleccionadas = [ruta for ruta in rutas if regex.match(ruta)]
print(seleccionadas)

El patrón se interpreta como una ruta y no como texto arbitrario. Por eso, los separadores de directorios son importantes y un asterisco normal no suele atravesarlos.

Patrones glob frente a expresiones regulares

Los globs fueron diseñados para ser simples. El asterisco representa una secuencia de caracteres, el signo de interrogación representa un carácter y los corchetes definen una clase. Las expresiones regulares ofrecen mucho más control, pero también son más difíciles de leer y mantener.

glob.translate crea un puente práctico entre ambas ideas. Los usuarios pueden escribir un filtro sencillo y el programa puede trabajar con una expresión regular compilada.

Búsqueda recursiva con doble asterisco

Cuando se utiliza recursive=True, el patrón ** puede representar varios niveles de directorios.

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

for ruta in rutas:
    if regex.match(ruta):
        print(ruta)

Sin la opción recursiva, no conviene asumir que ** recorrerá cualquier profundidad. Configura la opción de forma explícita para que el comportamiento sea claro.

Archivos y directorios ocultos

En sistemas Unix, los nombres que comienzan con punto son ocultos. La opción include_hidden controla si los comodines pueden coincidir con esos componentes. Esta diferencia es importante en analizadores de proyectos, copias de seguridad e indexadores, porque carpetas como .git, .venv y .cache pueden contener miles de archivos.

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

Incluso si solo comparas cadenas, conservar esta regla ayuda a reproducir el comportamiento esperado del módulo glob.

Separadores personalizados

La función puede trabajar con separadores específicos. Esto es útil cuando las rutas proceden de archivos ZIP, servicios remotos o almacenamiento de objetos. Los miembros de un ZIP suelen usar barras normales incluso en Windows.

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

Fijar el separador permite obtener resultados previsibles en diferentes sistemas operativos y simplifica las pruebas automatizadas.

glob.translate frente a fnmatch.translate

fnmatch.translate está orientado principalmente a nombres, mientras que glob.translate entiende segmentos de rutas. En una ruta, el separador funciona como límite especial. En una coincidencia de nombre, el valor suele tratarse como una sola secuencia.

Usa fnmatch para nombres simples como foto-*.jpg. Usa glob.translate cuando intervienen directorios, recursión, componentes ocultos o separadores configurables.

Compilar la expresión una sola vez

Si el mismo patrón se aplicará a miles de elementos, compila la expresión una vez y reutilízala.

def crear_filtro(patron, *, recursive=False):
    expresion = glob.translate(patron, recursive=recursive)
    return re.compile(expresion)

filtro = crear_filtro("logs/**/*.json", recursive=True)
resultados = [ruta for ruta in rutas if filtro.match(ruta)]

Si la aplicación recibe muchos patrones dinámicos, puedes utilizar una caché limitada. Evita almacenar un número ilimitado de expresiones compiladas.

Validación y seguridad

Los patrones glob no ejecutan código, pero un patrón demasiado amplio puede generar problemas de rendimiento. Una búsqueda que abarque todo un servidor, un bucket o un árbol enorme puede consumir demasiado tiempo y memoria.

En una aplicación web, no permitas que un patrón no confiable recorra cualquier carpeta. Restringe el directorio raíz, la profundidad, la longitud del patrón, el tiempo de ejecución y la cantidad de resultados. Cuando se trabaja con listas en memoria, también conviene limitar el tamaño de entrada.

Ejemplo con objetos de almacenamiento en la nube

Supongamos que una API devuelve claves de objetos y necesitas seleccionar imágenes de un cliente concreto.

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

patron = "clientes/acme/**/*.[pw][ne][gb]"
regex = re.compile(glob.translate(patron, recursive=True, seps="/"))
filtrados = [objeto for objeto in objetos if regex.match(objeto)]

Para muchas extensiones, puede ser más claro combinar un filtro de ruta con una comprobación del sufijo mediante pathlib. La claridad suele ser mejor que un patrón excesivamente ingenioso.

Normalización con pathlib

pathlib ofrece una API orientada a objetos. Puedes normalizar rutas remotas con PurePosixPath antes de aplicar el regex.

from pathlib import PurePosixPath

normalizadas = [PurePosixPath(ruta).as_posix() for ruta in objetos]
filtradas = [ruta for ruta in normalizadas if regex.match(ruta)]

Consulta también nuestros contenidos sobre pathlib en Python, expresiones regulares, el módulo os y archivos grandes.

Pruebas recomendadas

Incluye casos con archivos en la raíz, rutas profundas, componentes ocultos, separadores distintos, espacios, extensiones en mayúsculas, valores vacíos y coincidencias parciales.

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 ruta, esperado in casos.items():
    assert bool(filtro.match(ruta)) is esperado

Las pruebas son especialmente importantes cuando los patrones se guardan en archivos de configuración, porque un pequeño cambio puede incluir o excluir muchos elementos sin producir un error visible.

Errores comunes

Un error frecuente es esperar que * atraviese separadores. Otro es olvidar el tratamiento especial de nombres ocultos. También es común aplicar rutas de Windows a un filtro creado para rutas POSIX sin normalizar previamente.

Evita recompilar el mismo patrón dentro de un bucle. Traduce y compila antes de iterar. Tampoco dependas de detalles internos de la expresión generada; controla el comportamiento mediante los parámetros públicos.

Cuándo conviene usar glob.translate

Es una buena opción cuando necesitas una sintaxis amigable para usuarios y quieres aplicar el filtro fuera de una búsqueda directa en disco. Algunos casos son listados de almacenamiento en la nube, manifiestos ZIP, reglas de backup, herramientas de build, indexadores de código, descubrimiento de pruebas y pipelines de recursos.

Para consultar los detalles exactos, revisa la documentación oficial de glob y la documentación de re. Verifica la versión de Python cuando mantengas compatibilidad con intérpretes antiguos.

Conclusión

glob.translate combina la legibilidad de los patrones glob con la flexibilidad de las expresiones regulares compiladas. Si entiendes la recursión, los separadores, los archivos ocultos, la validación y las pruebas, puedes construir filtros portables y previsibles. Mantén los patrones limitados, normaliza las rutas y aplica restricciones cuando la entrada provenga de usuarios o sistemas externos.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Código Python con anotaciones y type hints en un portátil
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    annotationlib: resuelve anotaciones diferidas

    Aprende annotationlib en Python para recuperar anotaciones, referencias futuras y type hints con mayor seguridad.

    Ler mais

    Tempo de leitura: 7 minutos
    24/09/2026
    Persona programando en Python con SQLite y dbm.sqlite3
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    dbm.sqlite3: clave-valor con SQLite en Python

    Aprende dbm.sqlite3 en Python para almacenar pares clave-valor con SQLite, migrar datos, controlar concurrencia y medir rendimiento.

    Ler mais

    Tempo de leitura: 6 minutos
    23/09/2026
    Desarrollador trabajando con tareas asíncronas y TaskGroup eager_start en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    TaskGroup eager_start: controla el inicio de tareas

    Aprende a usar eager_start en asyncio.TaskGroup para controlar el inicio de tareas, la ejecución inmediata, el orden y la compatibilidad.

    Ler mais

    Tempo de leitura: 7 minutos
    23/09/2026
    Desarrolladora trabajando con tipado estático y typing.ReadOnly en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    typing.ReadOnly: campos de solo lectura en TypedDict

    Aprende typing.ReadOnly en Python para declarar claves de solo lectura en TypedDict y crear contratos de datos más seguros.

    Ler mais

    Tempo de leitura: 6 minutos
    22/09/2026
    Código Python que representa argumentos posicionales con functools.Placeholder
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    functools.Placeholder: argumentos medios en partial

    Aprende functools.Placeholder en Python para reservar argumentos intermedios en partial y crear callbacks y adaptadores más claros.

    Ler mais

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

    warnings.deprecated: marca APIs obsoletas

    Aprende warnings.deprecated en Python para marcar APIs obsoletas, orientar migraciones e integrar avisos con tipado, pruebas, documentación y CI.

    Ler mais

    Tempo de leitura: 6 minutos
    21/09/2026