Подтвердить что ты не робот

использование регулярных выражений в glob.glob для 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

Этот код работает для вывода списка файлов в текущей папке, в именах которых есть "abc", "123" или "a1b".

Как бы я использовал один шар для выполнения этой функции? Спасибо!

4b9b3361

Ответ 1

Самый простой способ - отфильтровать результаты glob самостоятельно. Вот как это сделать, используя простое понимание цикла:

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

Вы также можете использовать regexp и no 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

(Кстати, именование переменной list - плохая идея, поскольку list - тип Python...)

Ответ 2

Вот готовый к использованию способ сделать это, основываясь на других ответах. Это не самая высокая производительность, но работает, как описано.

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

Ответ 3

Я удивлен, что без ответов здесь используется фильтр.

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())

Он принимает любой итератор, который возвращает строки, включая списки, кортежи, дикты (если все ключи являются строками) и т.д. Если вы хотите поддерживать частичные совпадения, вы можете изменить .match на .search. Обратите внимание, что это, очевидно, возвращает генератор, поэтому, если вы хотите использовать результаты, не повторяя их, вы можете преобразовать результат в список самостоятельно или обернуть оператор return списком (...).

Ответ 4

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

Ответ 5

Re: Эван

Это работает для меня, только если я добавлю list() в функцию filter().

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

Надеюсь, это поможет.