web-dev-qa-db-fra.com

expression régulière en utilisant glob.glob de python

import glob

list = glob.glob(r'*abc*.txt') + glob.glob(r'*123*.txt') + glob.glob(r'*a1b*.txt')

for i in list:
  print i

Ce code fonctionne pour lister les fichiers du dossier courant qui ont 'abc' '123' ou 'a1b' dans leurs noms . Comment utiliser un glob pour rendre cette fonction fonctionnelle

25
user1561868

Le moyen le plus simple serait de filtrer vous-même les résultats globaux. Voici comment faire en utilisant une simple compréhension de boucle:

import glob
res = [f for f in glob.glob("*.txt") if "abc" in f or "123" in f or "a1b" in f]
for f in res:
    print f

Vous pouvez aussi utiliser une expression rationnelle sans glob:

import os
import re
res = [f for f in os.listdir(path) if re.search(r'(abc|123|a1b).*\.txt$', f)]
for f in res:
    print f

(Au fait, nommer une variable list est une mauvaise idée car list est un type Python ...)

39
Schnouki

Voici une façon de procéder, basée sur les autres réponses. Ce n'est pas la performance la plus critique, mais cela fonctionne comme décrit.

def reglob(path, exp, invert=False):
    """glob.glob() style searching which uses regex

    :param exp: Regex expression for filename
    :param invert: Invert match to non matching files
    """

    m = re.compile(exp)

    if invert is False:
        res = [f for f in os.listdir(path) if m.search(f)]
    else:
        res = [f for f in os.listdir(path) if not m.search(f)]

    res = map(lambda x: "%s/%s" % ( path, x, ), res)
    return res
11
sleepycal

Je suis surpris qu'aucune réponse ici utilisé filtre.

import os
import re

def glob_re(pattern, strings):
    return filter(re.compile(pattern).match, strings)

filenames = glob_re(r'.*(abc|123|a1b).*\.txt', os.listdir())

Cela accepte tous les itérateurs qui renvoient des chaînes, y compris des listes, des tuples, des dict (si toutes les clés sont des chaînes), etc. Si vous souhaitez prendre en charge des correspondances partielles, vous pouvez remplacer .match par .search. Veuillez noter que ceci renvoie évidemment un générateur. Ainsi, si vous souhaitez utiliser les résultats sans les parcourir, vous pouvez les convertir vous-même en liste, ou envelopper l'instruction de retour avec list (...).

3
Evan
for filename in glob.iglob(path_to_directory + "*.txt"):
    if filename.find("abc") != -1 or filename.find("123") != -1 or filename.find("a1b") != -1:
        print filename
0
R.Camilo