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 个组合out,因为有一个文件 fb2
(通配符的有效组合)不存在。
问题:如何获取每个通配符的有效匹配值列表?更准确地说:如何获取与实际存在的文件匹配的(字符串)值的元组列表?
在我的示例中,我想获取元组列表:[('a', '2'), ('b', '1'), ('a', '1') ]
。
注意:
- 我不想得到全名,只是通配符匹配的值(在我的示例中,前缀
'f'
不是通配符的一部分,因此我不想将其放入元组列表中); - 这必须适用于所有支持的通配符,包括 * 和 ?。
我能想到的唯一解决方案是使用正则表达式,但这基本上意味着重新实现整个 glob 机制以提取中间数据。
编辑
由于“过于宽泛”的问题(???),我得到了一个接近的提议,我将问题重新表述为:是否可以使用 glob/fnmatch 模块而不是直接使用正则表达式来获得该结果?
最佳答案
这些信息无法通过这些模块获得。 glob
调用 fnmatch
进行模式匹配,而 fnmatch
使用正则表达式进行模式匹配。查看glob和 fnmatch Python 源代码。
下面是一些 Python 2 演示代码,它使用 fnmatch
中的 translate
函数的修改版本。根据我的简短测试,它似乎 可以工作,但不提供任何保证。 :) 请注意,这会忽略 fnmatch
执行的其他操作,例如不区分大小写的匹配。
#!/usr/bin/env python
import re, fnmatch, glob
def pat_translate(pat):
"""Translate a shell PATTERN to a regular expression.
There is no way to quote meta-characters.
Hacked to add capture groups
"""
i, n = 0, len(pat)
res = ''
while i < n:
c = pat[i]
i = i+1
if c == '*':
res = res + '(.*)'
elif c == '?':
res = res + '(.)'
elif c == '[':
j = i
if j < n and pat[j] == '!':
j = j+1
if j < n and pat[j] == ']':
j = j+1
while j < n and pat[j] != ']':
j = j+1
if j >= n:
res = res + '\\['
else:
stuff = pat[i:j].replace('\\','\\\\')
i = j+1
if stuff[0] == '!':
stuff = '^' + stuff[1:]
elif stuff[0] == '^':
stuff = '\\' + stuff
res = '%s([%s])' % (res, stuff)
else:
res = res + re.escape(c)
return res + '\Z(?ms)'
def test(shell_pat):
print 'Shell pattern %r' % shell_pat
names = glob.glob(shell_pat)
print 'Found', names
regex = pat_translate(shell_pat)
print 'Regex %r' % regex
pat = re.compile(regex)
groups = [pat.match(name).groups() for name in names]
print 'name, groups'
for name, row in zip(names, groups):
print name, row
关于python - 从 python 的 glob 中提取所有扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31408219/