использование регулярных выражений в 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".
Как бы я использовал один шар для выполнения этой функции? Спасибо!
Ответы
Ответ 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))
Надеюсь, это поможет.