如何检查文件名是否与通配符模式匹配?

Ahe*_*eho 1 .net

我知道我能做到

Directory.GetFiles(@"c:\", "*.html")
Run Code Online (Sandbox Code Playgroud)

我将得到一个与*.html文件模式匹配的文件列表.

我想反过来.给定文件名abc.html,我想要一个方法,告诉我该文件名是否与*.html模式匹配.例如

class.method("abc.html", "*.html") // returns true
class.method("abc.xml", "*.html") // returns false
class.method("abc.doc", "*.?oc") // returns true
class.method("Jan24.txt", "Jan*.txt") // returns true
class.method("Dec24.txt", "Jan*.txt") // returns false
Run Code Online (Sandbox Code Playgroud)

该功能必须存在于dotnet中.我只是不知道它暴露在哪里.

将模式转换为正则表达式可能是一种方法.然而,它似乎有很多边缘情况,可能比它的价值更麻烦.

注意:问题中的文件名可能还不存在,所以我不能只包装一个Directory.GetFiles调用并检查结果集是否有任何条目.

Ale*_*der 7

最简单的方法是将通配符转换为正则表达式,然后应用它:

public static string WildcardToRegex(string pattern)
{
  return "^" + Regex.Escape(pattern).
  Replace("\\*", ".*").
  Replace("\\?", ".") + "$";
}
Run Code Online (Sandbox Code Playgroud)

但是如果由于某种原因你不能使用正则表达式,你可以编写自己的通配符匹配实现.你可以在这里找到一个.

这是从python实现移植的另一个:

using System;

class App
{
  static void Main()
  {
    Console.WriteLine(Match("abc.html", "*.html")); // returns true
    Console.WriteLine(Match("abc.xml", "*.html")); // returns false
    Console.WriteLine(Match("abc.doc", "*.?oc")); // returns true
    Console.WriteLine(Match("Jan24.txt", "Jan*.txt")); // returns true
    Console.WriteLine(Match("Dec24.txt", "Jan*.txt")); // returns false  
  }

  static bool Match(string s1, string s2)
  {
    if (s2=="*" || s1==s2) return true;
    if (s1=="") return false;

    if (s1[0]==s2[0] || s2[0]=='?') return Match(s1.Substring(1),s2.Substring(1));
    if (s2[0]=='*') return Match(s1.Substring(1),s2) || Match(s1,s2.Substring(1));
    return false;
  }
}
Run Code Online (Sandbox Code Playgroud)

  • @ I4V:我认为这不是RegEx的目的,您可以在进行匹配之前搜索无效的文件名字符,搜索Path.GetInvalidFileNameChars。 (2认同)