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'
的文件。
我该如何使用一个glob
函数来完成这个功能?
最简单的方法是自己筛选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
你也可以使用正则表达式而不是 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中的一个类型...)
或者 or
而不是 并且 and
? - Emmanuelor
实际上可能更合适。感谢您指出这一点。 - Schnouki我很惊讶这里没有使用筛选器的回答。
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。请注意,这显然返回一个生成器,因此如果您想在不迭代它们的情况下使用结果,可以自行将结果转换为列表,或者将返回语句包装在 list(...) 中。for path in glob_re(pattern, string): print(path)
- Evan这里有一个现成的方法可以做到这一点,基于其他答案。它不是最关键的性能问题,但它按描述工作;
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
match
来完全匹配名称。不要点踩。 - holdenwebres
列表推导式中完成,而不是第二次循环遍历所有匹配项。 - martineaufor 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