2013-03-26 97 views
1

我知道我可以做如何检查文件名是否匹配通配符模式?

Directory.GetFiles(@"c:\", "*.html") 

,我会得到匹配* .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 

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

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

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

回答

4

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

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

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

这里是另外一个从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; 
    } 
} 
+0

这对于无效的文件名不起作用。 'Match(“aaa/bbb.txt”,“* .txt”);'将返回* true * – I4V 2013-03-26 21:50:21

+1

原始问题不包含路径,只包含文件名匹配。但是您始终可以使用Path.GetFileName()提取文件名。 – Alexander 2013-03-27 07:20:55

+0

我说**无效的**文件名像'aaa/bbb.txt'。不*路径* – I4V 2013-03-27 16:54:23

0

我不认为GetFilessearchPattern并支持完整的正则表达式。下面的代码可以替代(但不是非常高效)

bool IsMatch(string fileName,string searchPattern) 
{ 
    try 
    { 
     var di = Directory.CreateDirectory("_TEST_"); 
     string fullName = Path.Combine(di.FullName, fileName); 
     using (File.Create(fullName)) ; 
     bool isMatch = di.GetFiles(searchPattern).Any(); 
     File.Delete(fullName); 
     return isMatch; 
    } 
    catch 
    { 
     return false; 
    } 
} 
相关问题