2016-07-21 13 views
0

Ich habe mehrere Fragen zu Stack Overflow über Directory.GetFiles() gefunden, aber in allen Fällen wird erläutert, wie Sie es verwenden können, um eine bestimmte Erweiterung zu finden oder eine Reihe von Dateien über mehrere Kriterien. Aber in meinem Fall, was ich will, ist ein Suchmuster für Directory.GetFiles() mit regulären Ausdrücken, die alle Dateien des Verzeichnisses aber die Menge, die ich angeben, zurückgeben. Ich meine nicht das Set, das ich will, sondern den Unterschied. Zum Beispiel, wenn ich alle Dateien eines Verzeichnisses haben möchte, aber nicht die htmls. Beachten Sie, dass, i‘, weiß m es auf diese Weise erreichen könnte:Verwenden von Directory.GetFiles(), um alle Dateien außer einer bestimmten Erweiterung auszuwählen

var filteredFiles = Directory 
.GetFiles(path, "*.*") 
.Where(file => !file.ToLower().EndsWith("html"))) 
.ToList(); 

Aber dies ist nicht eine sehr wiederverwendbare Lösung, wenn ich später für eine andere Art von Datei filtern möchte ich haben, um den Code zu ändern Hinzufügen eines || zum Where-Zustand. Ich suche nach etwas, das mir erlaubt, eine Regex zu erstellen, die in den Dateien besteht, die ich nicht bekommen will, und sie an Directory.GetFiles() weiterzugeben. Also, wenn ich später für weitere Erweiterungen filtern möchte, ändert sich nur die Regex.

+0

Siehe eine sehr ähnliche http://stackoverflow.com/questions/13301053/directory-getfiles-of-certain-extension –

Antwort

7

Sie brauchen nicht einen regulären Ausdruck, wenn Sie Erweiterung filtern möchten (s):

// for example a field or property in your class 
private HashSet<string> ExtensionBlacklist { get; } = 
    new HashSet<string>(StringComparer.InvariantCultureIgnoreCase) 
    { 
     ".html", 
     ".htm" 
    }; 
// ... 

var filteredFiles = Directory.EnumerateFiles(path, "*.*") 
    .Where(fn => !ExtensionBlacklist.Contains(System.IO.Path.GetExtension(fn))) 
    .ToList(); 
+0

Ich frage mich, wo der Break-even-Punkt zwischen diesem und einem Regex wäre, wie 'Enthält' wird Je länger das Array ist, desto langsamer. – Joey

+0

@Joey: Dann verwenden Sie stattdessen ein 'HashSet '. Es wird immer effizienter sein als Regex –

+0

Danke Tim. Du hast die Idee. Ist eine ziemlich saubere Lösung für mein Problem –

0

So im Wesentlichen nur Sie wissen nicht, wie eine Regex auf einen String auszuführen?

Für diesen Zweck gibt es Regex.IsMatch. Sie können jedoch auch den Code ändern, um die Erweiterung in einer Reihe von zu filternden Erweiterungen nachzuschlagen, wodurch Sie auch problemlos neue Filter hinzufügen können.

1

würde ich empfehlen, gegen die Verwendung von Regex für so etwas wie dieses:

var filteredFiles = Directory 
    .GetFiles(path, "*.*") 
    .Where(file => !excludedExtensions.Any<string>((extension) => 
    file.EndsWith(extension, StringComparison.CurrentCultureIgnoreCase))) 
    .ToList(); 

Sie es eine Sammlung Ihrer ausgeschlossenen Erweiterungen passieren kann, zB:

var excludedExtensions = new List<string>(new[] {".html", ".xml"}); 

Die Any wird Kurzschluss Sobald es eine Übereinstimmung auf einer ausgeschlossenen Erweiterung findet, denke ich, dass dies sogar excludedExtensions.Contains() vorzuziehen ist. Was die Regex anbelangt, glaube ich nicht, dass es einen guten Grund gibt, das zu benutzen, wenn man sich die Mühe machen muss, sie zu kaufen. Verwenden Sie Regex nicht, es sei denn, es ist das einzige Werkzeug für den Job.

+0

Danke für den Regex-Tipp Rory. Ich werde es mir merken –