ant有一个很好的方法来选择文件组,最简单的方法是使用**来指示目录树。例如。

**/CVS/*            # All files immediately under a CVS directory.
mydir/mysubdir/**   # All files recursively under mysubdir

这里可以看到更多的例子:
http://ant.apache.org/manual/dirtasks.html
您将如何在python中实现这一点,以便您可以执行以下操作:
files = get_files("**/CVS/*")
for file in files:
    print file

=>
CVS/Repository
mydir/mysubdir/CVS/Entries
mydir/mysubdir/foo/bar/CVS/Entries

最佳答案

一旦遇到**,就必须在整个目录结构中递归,所以我认为在这一点上,最简单的方法是使用os.walk遍历目录,构造一个路径,然后检查它是否与模式匹配。您可能可以通过以下方式转换为regex:

def glob_to_regex(pat, dirsep=os.sep):
    dirsep = re.escape(dirsep)
    print re.escape(pat)
    regex = (re.escape(pat).replace("\\*\\*"+dirsep,".*")
                           .replace("\\*\\*",".*")
                           .replace("\\*","[^%s]*" % dirsep)
                           .replace("\\?","[^%s]" % dirsep))
    return re.compile(regex+"$")

(不过请注意,这并不是完全功能化的——例如,它不支持[a-z]样式的glob模式,尽管这可能是可以添加的)。(第一个\*\*/匹配是覆盖像\*\*/CVS匹配./CVS这样的情况,并且在尾部只有\*\*匹配。)
但是,显然在不处理**模式时,您不想递归当前dir下的所有内容,所以我认为您需要一个两阶段的方法。我还没有尝试过实现下面的方法,可能还有一些角落的案例,但我认为应该是可行的:
在目录分隔符上拆分模式iepat.split('/') -> ['**','CVS','*']
在目录中递归,并查看此级别模式的相关部分即n levels deep -> look at pat[n]
如果pat[n] == '**'切换到上述策略:
使用dirsep.join(pat[n:])重建模式
转换为glob\_to\_regex()的正则表达式
在当前目录中递归地os.walk,建立相对于开始的级别的路径。如果路径与regex匹配,则放弃它。
如果pat与"**"不匹配,并且它是模式中的最后一个元素,则生成与glob.glob(os.path.join(curpath,pat[n]))匹配的所有文件/目录
如果pat不匹配"**",并且它不是模式中的最后一个元素,那么对于每个目录,检查它是否匹配(使用glob)pat[n]。如果是,则向下递归,增加深度(因此它将查看pat[n+1]

关于python - 您将如何在python中实现 Ant 风格的模式集以选择文件组?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/161755/

10-09 05:02