[英]How to filter a list of strings matching a pattern
I have a list of strings (file names actually) and I'd like to keep only those that match a filter expression like: \*_Test.txt
.我有一个字符串列表(实际上是文件名),我只想保留那些与过滤器表达式匹配的字符串,例如:
\*_Test.txt
。
What would be the best to achieve this?实现这一目标的最佳方法是什么?
Here is the answer that I came up with:这是我想出的答案:
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();
You probably want to use a regular expression for this if your patterns are going to be complex....如果您的模式很复杂,您可能希望为此使用正则表达式....
you could either use a proper regular expression as your filter (eg for your specific example it would be new Regex(@"^.*_Test\.txt$")
or you could apply a conversion algorithm.您可以使用适当的正则表达式作为过滤器(例如,对于您的具体示例,它将是
new Regex(@"^.*_Test\.txt$")
或者您可以应用转换算法。
Either way you could then just use linq to apply the regex.无论哪种方式,您都可以使用 linq 来应用正则表达式。
for example例如
var myRegex=new Regex(@"^.*_Test\.txt$");
List<string> resultList=files.Where(myRegex.IsMatch).ToList();
Some people may think the above answer is incorrect, but you can use a method group instead of a lambda.有些人可能认为上面的答案不正确,但是您可以使用方法组来代替 lambda。 If you wish the full lamda you would use:
如果你想要完整的 lamda,你会使用:
var myRegex=new Regex(@"^.*_Test\.txt$");
List<string> resultList=files.Where(f => myRegex.IsMatch(f)).ToList();
or non Linq或非 Linq
List<string> resultList=files.FindAll(delegate(string s) { return myRegex.IsMatch(s);});
if you were converting the filter a simple conversion would be如果您要转换过滤器,则简单的转换将是
var myFilter="*_Test.txt";
var myRegex=new Regex("^" + myFilter.Replace("*",".*") +"$");
You could then also have filters like "*Test*.txt"
with this method.然后,您还可以使用此方法使用
"*Test*.txt"
类的过滤器。
However, if you went down this conversion route you would need to make sure you escaped out all the special regular expression chars eg "."但是,如果您走这条转换路线,则需要确保您转义了所有特殊的正则表达式字符,例如“。” becomes @".", "(" becomes @"(" etc.......
变成@".", "(" 变成@"(" 等等......
Edit -- The example replace is TOO simple because it doesn't convert the.编辑——示例替换太简单了,因为它不转换。 so it would find
"fish_Textxtxt"
so escape atleast the .
所以它会找到
"fish_Textxtxt"
,所以至少逃脱.
so所以
string myFilter="*_Test.txt";
foreach(char x in @"\+?|{[()^$.#") {
myFilter = myFilter.Replace(x.ToString(),@"\"+x.ToString());
}
Regex myRegex=new Regex(string.Format("^{0}$",myFilter.Replace("*",".*")));
Have you tried LINQ:你试过LINQ:
List<string> resultList = files.Where(x => x.EndsWith("_Test.txt")).ToList();
or if you are running this on some old/legacy .NET version (< 3.5):或者,如果您在某些旧的/旧版 .NET 版本(< 3.5)上运行它:
List<string> resultList = files.FindAll(delegate(string s) {
return s.EndsWith("_Test.txt");
});
This worked for me and is fairly simple:这对我有用,而且相当简单:
List<string> keys = new List<string>();
//populate your list
var myregex = new Regex("^.+$");
List<string> matchlist = keys.Where(i=>myregex.IsMatch(i)).ToList();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.