python - 从 python 的 glob 中提取所有扩展

标签 python glob

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]。它们每个都匹配值 ab12,但这些值只有 3 个组合out,因为有一个文件 fb2(通配符的有效组合)不存在。

问题:如何获取每个通配符的有效匹配值列表?更准确地说:如何获取与实际存在的文件匹配的(字符串)值的元组列表?

在我的示例中,我想获取元组列表:[('a', '2'), ('b', '1'), ('a', '1') ]

注意:

  1. 我不想得到全名,只是通配符匹配的值(在我的示例中,前缀 'f' 不是通配符的一部分,因此我不想将其放入元组列表中);
  2. 这必须适用于所有支持的通配符,包括 * 和 ?。

我能想到的唯一解决方案是使用正则表达式,但这基本上意味着重新实现整个 glob 机制以提取中间数据。

编辑

由于“过于宽泛”的问题(???),我得到了一个接近的提议,我将问题重新表述为:是否可以使用 glob/fnmatch 模块而不是直接使用正则表达式来获得该结果?

最佳答案

这些信息无法通过这些模块获得。 glob 调用 fnmatch 进行模式匹配,而 fnmatch 使用正则表达式进行模式匹配。查看globfnmatch 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/

相关文章:

Python 类定义的差异

python - Pip 不使用垫片,而是使用 pyenv 的系统 'pip'

bash - 设置 nullglob 时关联数组未取消设置

angular - 使用具有多个通配符的 Globbing 模式在 TypeScript 中进行模块解析

javascript - 这 2 个 glob 模式有什么区别吗?

python - Twitter用户名的正则表达式

python - pandas 合并 Excel 电子表格

c - 调用 globfree() 时出现段错误

python - 将元组转换为类型未知的十六进制

php - 使用 PHP glob 获取文件夹 - 无限深度