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

C#如何获取匹配含多层通配符路径规则的所有目录

问题原因

.NET 原生的Directory.GetDirectories/Directory.EnumerateDirectories方法不支持跨路径段的通配符匹配:

  • 方法要求传入的基础路径必须是不含通配符的真实存在路径
  • 通配符*、?仅允许出现在最后一段搜索规则中,用于匹配当前层级的文件/文件夹
  • 路径前缀中包含通配符时,系统会直接判定为非法路径名,抛出System.IO.IOException,这就是两次代码运行报错的核心原因。
实现方案

方案1:无依赖原生递归实现

逐段解析路径规则,从固定根路径开始逐层匹配通配段,不需要引入第三方依赖,适配所有.NET版本:

using System.IO;
using System.Collections.Generic;
using System.Linq;

public static IEnumerable<string> MatchDirectories(string pathPattern)
{
    // 拆分路径为独立段,兼容正反斜杠分隔符
    var segments = pathPattern.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
                              .Where(s => !string.IsNullOrEmpty(s))
                              .ToList();
    
    // 初始化根路径(Windows下为盘符根目录,比如c:\)
    var currentDirs = new List<string> { segments[0] + Path.DirectorySeparatorChar };

    for (int i = 1; i < segments.Count; i++)
    {
        var rule = segments[i];
        var nextMatched = new List<string>();
        foreach (var dir in currentDirs)
        {
            // 当前段无通配符,直接拼接路径校验存在性
            if (!rule.Contains('*') && !rule.Contains('?'))
            {
                var target = Path.Combine(dir, rule);
                if (Directory.Exists(target)) nextMatched.Add(target);
                continue;
            }
            // 当前段含通配符,枚举当前层级所有匹配的子目录
            nextMatched.AddRange(Directory.EnumerateDirectories(dir, rule));
        }
        currentDirs = nextMatched;
        if (!currentDirs.Any()) break;
    }
    return currentDirs;
}

调用方式:

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

运行后返回结果完全符合预期:

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

方案2:使用官方Glob匹配库

如果项目可以引入NuGet包,可以使用微软官方提供的Microsoft.Extensions.FileSystemGlobbing库,原生支持多级通配、**任意层级匹配等复杂规则,不需要自己实现递归逻辑:

  1. 先在项目中安装NuGet包:Microsoft.Extensions.FileSystemGlobbing
  2. 匹配目录代码如下:
using Microsoft.Extensions.FileSystemGlobbing;
using Microsoft.Extensions.FileSystemGlobbing.Abstractions;

var matcher = new Matcher();
// 添加匹配规则,注意规则中使用正斜杠作为路径分隔符
matcher.AddInclude("logs/v*/api*/*");
// 从c盘根目录开始执行匹配
var matchResult = matcher.Execute(new DirectoryInfoWrapper(new DirectoryInfo(@"c:\")));
// 提取匹配到的目录全路径
var result = matchResult.Files
    .Select(f => Directory.GetParent(Path.GetFullPath(Path.Combine(@"c:\", f.Path))).FullName)
    .Distinct()
    .ToList();
注意事项
  • 不要尝试直接将多段带通配符的路径传入原生Directory类的搜索方法,该类方法从设计上就不支持该场景
  • 自定义递归实现时,推荐使用EnumerateDirectories代替GetDirectories,前者是延迟枚举,大目录场景下内存占用更低。

内容的提问来源于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 13:15:40