2009-07-08 13 views
1

J'ai un IEnumerable <DirectoryInfo> que je veux filtrer en utilisant un tableau d'expressions régulières pour trouver les correspondances potentielles. J'ai essayé de rejoindre mon répertoire et les chaînes regex en utilisant linq, mais je n'arrive pas à le faire correctement. Voici ce que j'essaie de faire ...Recherche de répertoires correspondants à l'aide d'une liste d'expressions régulières

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; 

... des suggestions pour que ça marche?

Répondre

4

Si vous ne souhaitez que des répertoires qui correspondent à toutes les expressions régulières.

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

Si vous souhaitez uniquement des répertoires correspondant à au moins une expression régulière.

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

Ah, bon appel sur le Any(). Je n'arrête pas d'oublier ceux-là! –

+0

Doh! - J'oublie tous ceux (Any & All) tout le temps aussi. –

0

vous manquez votre mot-clé Où en face de la jointure

2

Je ne pense pas que l'approche que vous prenez est exactement ce que vous voulez de toute façon. Cela va vérifier le nom contre toutes les chaînes regex, plutôt que de court-circuit sur le premier match. De plus, il dupliquerait les répertoires si l'un correspondait à plus d'un modèle.

Je pense que vous voulez quelque chose comme:

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 bonne réponse. –

Questions connexes