2009-07-08 12 views
1

Ich habe eine IEnumerable <DirectoryInfo>, die ich mit einem Array von regulären Ausdrücken filtern soll, um die möglichen Übereinstimmungen zu finden. Ich habe versucht, mein Verzeichnis und Regex-Strings mit Linq, aber es scheint nicht richtig zu machen. Hier ist, was ich versuche zu tun ...Finde übereinstimmende Verzeichnisse mit einer Liste von regulären Ausdrücken

string[] regexStrings = ... // some regex match code here. 

// get all of the directories below some root that match my initial criteria. 
var directories = from d in root.GetDirectories("*", SearchOption.AllDirectories) 
        where (d.Attributes & (FileAttributes.System | FileAttributes.Hidden)) == 0 
         && (d.GetDirectories().Where(dd => (dd.Attributes & (FileAttributes.System | FileAttributes.Hidden)) == 0).Count() > 0// has directories 
          || d.GetFiles().Where(ff => (ff.Attributes & (FileAttributes.Hidden | FileAttributes.System)) == 0).Count() > 0) // has files) 
        select d; 

// filter the list of all directories based on the strings in the regex array 
var filteredDirs = from d in directories 
        join s in regexStrings on Regex.IsMatch(d.FullName, s) // compiler doesn't like this line 
        select d; 

... irgendwelche Vorschläge, wie ich dies zur Arbeit bekommen kann?

Antwort

4

Wenn Sie nur Verzeichnisse wollen, die alle regulären Ausdrücken entsprechen.

var result = directories 
    .Where(d => regexStrings.All(s => Regex.IsMatch(d.FullName, s))); 

Wenn Sie nur Verzeichnisse wollen, dass mindestens einer regulären Ausdrücken entsprechen.

var result = directories 
    .Where(d => regexStrings.Any(s => Regex.IsMatch(d.FullName, s))); 
+0

Ah, guten Ruf auf die Any(). Ich vergesse das immer wieder! –

+0

Doh! - Ich vergesse die (Any & All) auch die ganze Zeit. –

2

Ich glaube nicht, dass der Ansatz Sie nehmen genau das, was Sie sowieso wollen. Das wird den Namen gegen ALL Regex-Strings überprüfen, anstatt einen Kurzschluss bei der ersten Übereinstimmung zu machen. Darüber hinaus würde es die Verzeichnisse duplizieren, wenn mehr als ein Muster übereinstimmte.

Ich glaube, Sie wollen so etwas wie:

string[] regexStrings = ... // some regex match code here. 

// get all of the directories below some root that match my initial criteria. 
var directories = from d in root.GetDirectories("*", SearchOption.AllDirectories) 
        where (d.Attributes & (FileAttributes.System | FileAttributes.Hidden)) == 0 
         && (d.GetDirectories().Where(dd => (dd.Attributes & (FileAttributes.System | FileAttributes.Hidden)) == 0).Count() > 0// has directories 
          || d.GetFiles().Where(ff => (ff.Attributes & (FileAttributes.Hidden | FileAttributes.System)) == 0).Count() > 0) // has files) 
        select d; 

// filter the list of all directories based on the strings in the regex array 
var filteredDirs = directories.Where(d => 
    { 
     foreach (string pattern in regexStrings) 
     { 
      if (System.Text.RegularExpressions.Regex.IsMatch(d.FullName, pattern)) 
      { 
       return true; 
      } 
     } 

     return false; 
    }); 
+0

+1 gute Antwort. –