You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#如何优雅实现匹配多层通配符的目录枚举

多段路径通配符匹配目录问题

我的文件夹结构如下:

c:\logs\v1\api1
c:\logs\v1\api2
c:\logs\v2\api1
c:\logs\v2\api2
c:\logs\other

我需要获取匹配如下通配符模式的所有文件夹:

c:\logs\v*\api*

预期返回的目录列表为:

c:\logs\v1\api1
c:\logs\v1\api2
c:\logs\v2\api1
c:\logs\v2\api2

无效实现尝试

直接传入带多层通配符的路径

以下写法无法正常运行:

var result = Directory.GetDirectories(@"c:\logs\v*\api*");

运行时抛出异常:
System.IO.IOException: 'The filename, directory name, or volume label syntax is incorrect. : 'c:\logs\v*\api*''

拆分磁盘根目录后传入搜索模式

以下尝试同样无法正常运行:

var directory = @"c:\logs\v*\api*";
var rootDirectory = Directory.GetDirectoryRoot(directory);
var remainingPath = directory.Substring(rootDirectory.Length);
Console.WriteLine($"remainingPath: {remainingPath}");

var result = Directory.GetDirectories(rootDirectory, remainingPath);

运行时抛出异常:
System.IO.IOException: 'The filename, directory name, or volume label syntax is incorrect. : 'c:\logs\v*''

可用但不够简洁的实现

递归逐段匹配实现

如下递归逐段匹配的实现可以正常生效:

public static IEnumerable<string> ResolveDirectories(string path)
{
    if (path.Contains("*") || path.Contains("?"))
    {
        var parts = new Regex(@"[\/](?=[^\/]*[\*?])").Split(path, 2);
        var searchRoot = parts[0];
        var searchPatterns = parts[1].Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
        foreach (var dir in ResolveWildcards(searchRoot, searchPatterns))
            yield return dir;
    }
    else
    {
        yield return path;
    }
}

public static IEnumerable<string> ResolveWildcards(string searchRoot, string[] searchPatterns)
{
    if (Directory.Exists(searchRoot))
    {
        // 取下一级匹配规则在当前目录搜索
        var next = searchPatterns[0];
        // 剩余匹配规则留待递归处理
        var rest = searchPatterns.Skip(1).ToArray();

        if (!searchRoot.EndsWith("\\"))
            searchRoot += "\\";

        foreach (var dir in Directory.EnumerateDirectories(searchRoot, next))
        {
            // 已经是最后一级匹配规则,直接返回结果
            if (rest.Length == 0)
                yield return dir;
            else
            {
                // 非最后一级,用剩余规则在新找到的目录下继续搜索
                foreach (var sub in ResolveWildcards(dir, rest))
                    yield return sub;
            }
        }
    }
}

但该实现的代码写法不够简洁。

全量遍历+正则匹配实现

参考@Alessandro_D'Andria提供的思路,我实现了如下版本:

public static IEnumerable<string> ResolveDirectories(string path)
{
    var parts = new Regex(@"[\/](?=[^\/]*[\*?])").Split(path, 2);
    var root = parts[0];
    var part = @".*\\" + parts[1].Replace(@"\", @"\\");

    var regex = new Regex(part);
    var dirs = Directory
            .EnumerateDirectories(
                root,
                "*",
                SearchOption.AllDirectories)
            .Where(x => regex.IsMatch(x))
            .ToList();

    return dirs;
}

上述两种实现都较为繁琐,想了解是否存在更优雅的实现方案?


内容的提问来源于stack exchange,提问作者dafie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 23:54:33