匹配所有不以前缀开头的文件的全局模式
Glob pattern to match all files that do not start with prefix
我想使用 glob 模式来匹配 src/
文件夹中不以两个大写字母后跟一个点作为前缀的所有文件。
glob 应匹配以下文件
foo.txt
foo-bar.txt
foo.bar.baz.txt
fo.txt
但它不应该匹配以下文件:
AB.foo.txt
AB.foo-bar.txt
XY.foo.bar.baz.txt
FO.fo.txt
前缀始终是两个大写字母(A 到 Z)后跟一个点。
下面的怎么样(使用listdir)
from os import listdir
file_list = [f for f in listdir('./src') if not (f[0].isupper() and f[1].isupper() and f[2] == '.')]
glob()
基本上可以满足您的需求,但有一些限制。
你可以这样做:
glob.glob("src/[!A-Z][!A-Z][!.]*")
这将排除任何以两个大写字母后跟一个点开头的文件。但是,此特定语法还将排除文件名中少于 3 个字符的任何文件。 Globbing 类似于 shell 文件名 globbing 语法,在 shell 中,您要查找的内容通常使用 find
或 grep
.
来完成
如果 glob()
不够灵活,您必须自己对所有文件进行全局匹配和模式匹配。
这个解决方案也使用 listdir,但使用正则表达式来获取我们需要的内容。
from os import listdir
import re
# Fetch any file not match Captial head kind. If non-text file exist in the directory, it might fetch it either.
file_list = [f for f in listdir('./src') if not re.match(r'[A-Z][A-Z]\..*', f)]
# Fetch any file not match Captial head kind. Fetch txt only
file_list = [f for f in listdir('./src') if not re.match(r'[A-Z][A-Z]\..*', f) and re.match(r'.*txt', f)]
如果您查看 glob.py,您会发现它使用 fnmatch.filter
来过滤路径。
fnmatch.filter
使用 fnmatch.translate
从模式中形成正则表达式。
因此,可以使用 glob.glob("[!A-Z][!A-Z]*")
(将转换为以下正则表达式:'(?s:[^A-Z][^A-Z].*)\Z'
.
请注意,这将忽略前两个索引中包含大写字母的所有内容。函数translate
定义如下:
def translate(pat):
"""Translate a shell PATTERN to a regular expression.
There is no way to quote meta-characters.
"""
所以我相信没有办法包含更复杂的正则表达式。
我想使用 glob 模式来匹配 src/
文件夹中不以两个大写字母后跟一个点作为前缀的所有文件。
glob 应匹配以下文件
foo.txt
foo-bar.txt
foo.bar.baz.txt
fo.txt
但它不应该匹配以下文件:
AB.foo.txt
AB.foo-bar.txt
XY.foo.bar.baz.txt
FO.fo.txt
前缀始终是两个大写字母(A 到 Z)后跟一个点。
下面的怎么样(使用listdir)
from os import listdir
file_list = [f for f in listdir('./src') if not (f[0].isupper() and f[1].isupper() and f[2] == '.')]
glob()
基本上可以满足您的需求,但有一些限制。
你可以这样做:
glob.glob("src/[!A-Z][!A-Z][!.]*")
这将排除任何以两个大写字母后跟一个点开头的文件。但是,此特定语法还将排除文件名中少于 3 个字符的任何文件。 Globbing 类似于 shell 文件名 globbing 语法,在 shell 中,您要查找的内容通常使用 find
或 grep
.
如果 glob()
不够灵活,您必须自己对所有文件进行全局匹配和模式匹配。
这个解决方案也使用 listdir,但使用正则表达式来获取我们需要的内容。
from os import listdir
import re
# Fetch any file not match Captial head kind. If non-text file exist in the directory, it might fetch it either.
file_list = [f for f in listdir('./src') if not re.match(r'[A-Z][A-Z]\..*', f)]
# Fetch any file not match Captial head kind. Fetch txt only
file_list = [f for f in listdir('./src') if not re.match(r'[A-Z][A-Z]\..*', f) and re.match(r'.*txt', f)]
如果您查看 glob.py,您会发现它使用 fnmatch.filter
来过滤路径。
fnmatch.filter
使用 fnmatch.translate
从模式中形成正则表达式。
因此,可以使用 glob.glob("[!A-Z][!A-Z]*")
(将转换为以下正则表达式:'(?s:[^A-Z][^A-Z].*)\Z'
.
请注意,这将忽略前两个索引中包含大写字母的所有内容。函数translate
定义如下:
def translate(pat):
"""Translate a shell PATTERN to a regular expression.
There is no way to quote meta-characters.
"""
所以我相信没有办法包含更复杂的正则表达式。