2011-08-10 13 views
11

Dizelerimin bir listesi (aslında dosya adları) ve yalnızca bir filtre ifadesiyle eşleşenleri tutmak istiyorum: \*_Test.txt.Bir desenle eşleşen dizelerin bir süzgeci nasıl filtrelenir

Bunu başarmak için en iyi ne olurdu?

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

veya bazı eski/eski .NET sürümü bu çalıştırıyorsanız (:

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(); 
+0

\ * .t \ * veya herhangi bir sayıda kombinasyon . \ * 'Yi kaldırmak bana kısmi eşleşme vermez. – TeamWild

+0

Eeep, cevabım için bir düzeltme dizgisini değiştirmeniz gerekiyor. '' ("^ {0} $") 'ya dönüştüğünde, aksi takdirde' 'fish_Test.txtWIBBLE '' ' –

cevap

18

muhtemelen wan Eğer desenleriniz karmaşık olacaksa, düzenli bir ifadeyi kullanmak için t .... Eğer buradaki örnekleriniz karmaşık olacaksa ... (örneğin, belirli bir örneğiniz için new Regex(@"^.*_Test\.txt$") olabilir) dönüşüm algoritması.

Her iki durumda da regex'i uygulamak için linq kullanabilirsiniz. Örneğin

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

Bazı insanlar yukarıdaki cevap yanlış düşünebilirler, ama bir lambda yerine yöntemi grubu kullanabilir için

. Tam lamda isterseniz kullanırsınız:

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

veya olmayan Linq filtreyi dönüştürme olsaydı

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

basit bir dönüşüm

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

Ardından da olabilir olurdu Bu yöntemle "*Test*.txt" gibi filtreler. Ancak, bu dönüşüm yolunu aştıysanız, tüm özel düzenli ifade karakterlerini çıkardığınızdan emin olmanız gerekir, örn. "" @ "olur.", "(" olur "" ("etc .......

Düzenleme - Örnek değiştirileceği için basittir. Bu nedenle, "fish_Textxtxt"'u bulamaz. en az .

yüzden

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

LINQ denediniz: Burada

ben ile geldi cevaptır < 3.5):

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

' 'ifadesini bulursunuz. Daha esnek, ama belki de karmaşık bir şey istiyorum. http://msdn.microsoft.com/en-us/library/ms228595% 28v = VS.100% 29.aspx – Johnny5

+0

Her zaman bir baş ağrısıyla bittiği için regex kullanmadan hızlı bir yol olacağını umuyordum. LINQ'yi kullanabilirim, böylece onu deneyecek ve ne olacağını göreceğim. – TeamWild

1

Bu benim için çalıştı ve oldukça basittir:. Ben bu yüzden \ * \ * veya kullanabilir esnek olması filtreyi istiyorum

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