Tea*_*ild 18 c# pattern-matching
我有一个字符串列表(实际上是文件名),我只想保留那些匹配过滤器表达式的字符串,如:\*_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();
Run Code Online (Sandbox Code Playgroud)
Bob*_*ale 32
如果您的模式变得复杂,您可能想要使用正则表达式....
您可以使用正确的正则表达式作为过滤器(例如,对于您的具体示例,它new Regex(@"^.*_Test\.txt$")可以应用转换算法.
无论哪种方式,您都可以使用linq来应用正则表达式.
例如
var myRegex=new Regex(@"^.*_Test\.txt$");
List<string> resultList=files.Where(myRegex.IsMatch).ToList();
Run Code Online (Sandbox Code Playgroud)
有些人可能认为上面的答案不正确,但您可以使用方法组而不是lambda.如果您希望使用完整的lamda:
var myRegex=new Regex(@"^.*_Test\.txt$");
List<string> resultList=files.Where(f => myRegex.IsMatch(f)).ToList();
Run Code Online (Sandbox Code Playgroud)
或非林克
List<string> resultList=files.FindAll(delegate(string s) { return myRegex.IsMatch(s);});
Run Code Online (Sandbox Code Playgroud)
如果您正在转换过滤器,则会进行简单的转换
var myFilter="*_Test.txt";
var myRegex=new Regex("^" + myFilter.Replace("*",".*") +"$");
Run Code Online (Sandbox Code Playgroud)
然后,您也可以"*Test*.txt"使用此方法的过滤器.
但是,如果你沿着这条转换路线走下去,你需要确保你逃脱了所有特殊的正则表达式字符,例如"." 变成@".","("成为@"("等......)
编辑 - 示例替换是TOO简单,因为它不转换.所以它会发现"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("*",".*")));
Run Code Online (Sandbox Code Playgroud)
你试过LINQ:
List<string> resultList = files.Where(x => x.EndsWith("_Test.txt")).ToList();
Run Code Online (Sandbox Code Playgroud)
或者如果您在某些旧版/旧版.NET(<3.5)上运行此版本:
List<string> resultList = files.FindAll(delegate(string s) {
return s.EndsWith("_Test.txt");
});
Run Code Online (Sandbox Code Playgroud)