web-dev-qa-db-ja.com

パターンに一致する文字列のリストをフィルタリングする方法

文字列(実際にはファイル名)のリストがあり、次のようなフィルター式に一致する文字列だけを保持したいと思います。\*_Test.txt

これを達成するために何が最善でしょうか?

これが私が思いついた答えです:

List<string> files = new List<string>();
files.Add("MyFile1.csv");
files.Add("MyFile1_Test.txt");
files.Add("MyFile2.csv");
files.Add("MyFile2_Test.txt");
files.Add("MyFile3.csv");
files.Add("MyFile3_Test.txt");
files.Add("MyFile_Testtxttxt.txt");

// Define a filter
string filter = "*_Test.txt";

// Make the filter regex safe
foreach (char x in @"\+?|{[()^$.#")
    filter = filter.Replace(x.ToString(), @"\" + x.ToString());

filter = string.Format("^{0}$",filter.Replace("*", ".*"));

// Old School
List<string> resultList1 = files.FindAll(delegate(string s) { return Regex.IsMatch(s, filter, RegexOptions.IgnoreCase); });

// Version using LINQ
List<string> resultList2 = files.Where(x =>  Regex.IsMatch(x, filter, RegexOptions.IgnoreCase) == true ).ToList();
19
TeamWild

パターンが複雑になる場合は、正規表現を使用することをお勧めします。

フィルターとして適切な正規表現を使用することもできます(たとえば、特定の例ではnew Regex(@"^.*_Test\.txt$")になるか、変換アルゴリズムを適用できます)。

どちらの方法でも、linqを使用して正規表現を適用できます。

例えば

var myRegex=new Regex(@"^.*_Test\.txt$");
List<string> resultList=files.Where(myRegex.IsMatch).ToList();

上記の答えは正しくないと考える人もいるかもしれませんが、ラムダの代わりにメソッドグループを使用できます。完全なラムダが必要な場合は、次を使用します。

var myRegex=new Regex(@"^.*_Test\.txt$");
List<string> resultList=files.Where(f => myRegex.IsMatch(f)).ToList();

または非Linq

List<string> resultList=files.FindAll(delegate(string s) { return myRegex.IsMatch(s);});

フィルターを変換する場合、単純な変換は

 var myFilter="*_Test.txt";
 var myRegex=new Regex("^" + myFilter.Replace("*",".*") +"$");

次に、"*Test*.txt"このメソッドを使用します。

ただし、この変換ルートをたどった場合は、特別な正規表現の文字をすべてエスケープする必要があります。 「」 @ "。"、 "("は@ "("などになります。

編集-変換例は変換しないため、非常に単純です。だから"fish_Textxtxt"したがって、少なくとも.

そう

string myFilter="*_Test.txt";
foreach(char x in @"\+?|{[()^$.#") {
  myFilter = myFilter.Replace(x.ToString(),@"\"+x.ToString());
}
Regex myRegex=new Regex(string.Format("^{0}$",myFilter.Replace("*",".*")));
30
Bob Vale

LINQを試しましたか?

List<string> resultList = files.Where(x => x.EndsWith("_Test.txt")).ToList();

またはこれを古い/レガシー.NETバージョン(<3.5)で実行している場合:

List<string> resultList = files.FindAll(delegate(string s) { 
    return s.EndsWith("_Test.txt"); 
});
8
Darin Dimitrov

これは私にとってはうまくいき、かなり簡単です:

List<string> keys = new List<string>();
//populate your list
var myregex = new Regex("^.+$");
List<string> matchlist = keys.Where(i=>myregex.IsMatch(i)).ToList();
1
Chad Kuehn