Python的glob模块允许指定通配符来列出文件,并且文件非常实用。
但是如何获取/重建通配符匹配的值?
例如,假设我有这8个文件:fa1 fa2 fa3 fb1 fb3 fc1 fc2 fc3
(注意:fb2
丢失了。)
我能做到
import glob
glob.glob('f[ab][12]') # ['fa2', 'fb1', 'fa1']
在这种情况下,我有2个通配符:[ab]
和[12]
。它们中的每一个都匹配值a
,b
和1
以及2
,但这些值只有3种组合,因为一个文件fb2
(一个有效的通配符组合`)不存在。
问题: 如何获取每个通配符的有效匹配值列表?更确切地说:如何获得与实际现有文件匹配的(字符串)值的元组列表?
在我的示例中,我想获取元组列表:[('a', '2'), ('b', '1'), ('a', '1')]
。
请注意:
'f'
不是通配符的一部分,因此我不想获得它在元组列表中); 我能想到的唯一解决方案是使用正则表达式,但这基本上意味着重新实现整个glob机制来提取中间数据。
由于我提出了一个过于宽泛的提案,因此我提出了一个非常广泛的提案。问题(???),我将问题重新表述为:是否可以使用glob / fnmatch模块获得该结果而不使用直接正则表达式?
答案 0 :(得分:1)
在您的具体情况下,您可能希望使用itertools.product
:
import itertools
import os
def get_wildcards(*specs):
for wildcard in itertools.product(*specs):
if os.path.exists('f{}{}'.format(*wildcard)):
yield wildcard
for wildcard in get_wildcards('ab', '12'):
print wildcard
输出:
('a', '1')
('a', '2')
('b', '1')
在这种情况下,您正在使用"产品" " ab" 和" 12" ,最后得到4个元组,os.path.exists
测试消除那些元组不要指定现有文件。
计划是将文件系统通配符转换为正则表达式(您可以避免使用正则表达式,但这会很痛苦)。接下来,我们将列出当前目录中的所有文件,将每个文件与正则表达式进行匹配。如果找到匹配,我们将构造一个元组来产生它。
import re
import os
def regex_from_wildcard(wildcard):
wildcard = wildcard.replace('.', r'\.')
wildcard = wildcard.replace('[', '([').replace(']', '])')
wildcard = wildcard.replace('?', r'(.)').replace('*', r'(.*)')
wildcard = r'^{}$'.format(wildcard)
wildcard = re.compile(wildcard)
return wildcard
def generate_from_wildcards(wildcard):
pattern = regex_from_wildcard(wildcard)
for filename in os.listdir('.'):
match_object = re.match(pattern, filename)
if match_object:
yield tuple(''.join(match_object.groups()))
# Test
for tup in generate_from_wildcards('f[bc]?'):
print tup
几点说明:
f
,一个点,那么这些不包含在元组中。