3

私は私ができることを知っています

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 に存在する必要があります。どこが露出してるのかさっぱりわからない。

パターンを正規表現に変換することが 1 つの方法かもしれません。ただし、多くのエッジケースがあり、価値がある以上に問題が発生する可能性があるようです。

注: 問題のファイル名はまだ存在しない可能性があるため、Directory.GetFiles 呼び出しをラップして、結果セットにエントリがあるかどうかを確認することはできません。

4

2 に答える 2

9

最も簡単な方法は、ワイルドカードを正規表現に変換してから適用することです。

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

ただし、何らかの理由で正規表現を使用できない場合は、ワイルドカード マッチングの独自の実装を作成できます。ここで見つけることができます。

Python 実装から移植された別のものを次に示します (編集 2020-07: IndexOutOfRangeException を修正):

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=="" || s2=="") 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;
  }
}
于 2013-03-26T20:26:39.337 に答える
0

完全な正規表現をサポートしているとsearchPatternは思いません。GetFiles以下のコードは代替手段になる可能性があります(ただし、パフォーマンスは高くありません)

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;
    }
}
于 2013-03-26T20:39:50.600 に答える