Python glob,但针对字符串列表而不是文件系统

问题描述 投票:40回答:6

我希望能够将glob格式的模式匹配到字符串列表,而不是文件系统中的实际文件。有什么方法可以做到这一点,或将glob模式轻松转换为正则表达式吗?

python regex python-2.7 glob
6个回答
15
投票

好艺术家复制品;伟大的艺术家glob

我偷了;)

steal分别将小球fnmatch.translate?转换为正则表达式*.。我没有调整。

.*

这一个import re def glob2re(pat): """Translate a shell PATTERN to a regular expression. There is no way to quote meta-characters. """ i, n = 0, len(pat) res = '' while i < n: c = pat[i] i = i+1 if c == '*': #res = res + '.*' res = res + '[^/]*' elif c == '?': #res = res + '.' 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)' fnmatch.filterre.match都起作用。

re.search

在此页面上找到的Glob模式和字符串通过测试。

def glob_filter(names,pat):
    return (name for name in names if re.match(glob2re(pat),name))

30
投票

pat_dict = { 'a/b/*/f.txt': ['a/b/c/f.txt', 'a/b/q/f.txt', 'a/b/c/d/f.txt','a/b/c/d/e/f.txt'], '/foo/bar/*': ['/foo/bar/baz', '/spam/eggs/baz', '/foo/bar/bar'], '/*/bar/b*': ['/foo/bar/baz', '/foo/bar/bar'], '/*/[be]*/b*': ['/foo/bar/baz', '/foo/bar/bar'], '/foo*/bar': ['/foolicious/spamfantastic/bar', '/foolicious/bar'] } for pat in pat_dict: print('pattern :\t{}\nstrings :\t{}'.format(pat,pat_dict[pat])) print('matched :\t{}\n'.format(list(glob_filter(pat_dict[pat],pat)))) 模块将glob用于单个路径元素

这意味着路径分为目录名和文件名,如果目录名包含元字符(包含字符fnmatch modulefnmatch[中的任何字符),则将它们扩展递归] >。

如果您有简单文件名的字符串列表,那么仅使用*就足够了:

?

但是如果它们包含完整路径,您需要做更多的工作,因为生成的正则表达式不会考虑路径段(通配符不会排除分隔符,也不会针对跨平台路径匹配进行调整)。

您可以从路径构造一个简单的fnmatch.filter() function,然后将其与之匹配:

fnmatch.filter()

这个满口可以使用路径上任意位置的glob快速找到匹配项:

import fnmatch

matching = fnmatch.filter(filenames, pattern)

10
投票

在Python 3.4+上,您只能使用trie


2
投票

虽然pathlib.PurePath(path_string).match(pattern) 可直接用于检查模式是否与文件名匹配,但是您也可以使用pathlib from PyPI方法从给定的pathlib模式中生成正则表达式:


1
投票

没关系,我找到了。我需要fnmatch.fnmatch模块。


0
投票

@ Veedrac fnmatch.translate答案的扩展名,可以应用于字符串列表:

© www.soinside.com 2019 - 2024. All rights reserved.