Hallo,
mit Directory.GetFiles ist es möglich, mit einem SearchPattern (z.B. .txt) zu suchen. Etwas wie ".txt; *.jpg" funktioniert dabei leider nicht.
Hinzu kommt, dass ich Filter wie z.B. "hall.*t" habe. Genauso könnte es sein, dass gerade diese gefilterten Dateien NICHT gesucht / benutzt werden sollen.
Nun meine Frage: Wie kann ich die Dateien filtern? Gibts es schon etwas vorgefertigtes in .NET? Vielleicht mit Regex?
Vielen Dank!
Gruß Dennis
Hallo,
ich glaube ich es gerade selber hinbekommen. Bis jetzt hat es funktioniert:
private bool FileMatchFilter(string file, string filter, bool ignoreCase)
{
if (ignoreCase)
{
file = file.ToLower();
filter = filter.ToLower();
}
if (file == filter)
return true;
string[] searchParts = filter.Split('*');
if ((filter[0] != '*') && (!file.StartsWith(searchParts[0])))
{
return false;
}
if ((filter[filter.Length - 1] != '*') && (!file.EndsWith(searchParts[searchParts.Length - 1])))
{
return false;
}
foreach (string searchPart in searchParts)
{
if (!string.IsNullOrEmpty(searchPart))
{
if (!file.Contains(searchPart))
{
return false;
}
}
}
return true;
}
Gruß Dennis
Hallo,
ich glaube ich es gerade selber hinbekommen. Bis jetzt hat es funktioniert:
vielleicht hab' ich's nicht ganz verstanden, aber warum teilst Du die Suchmuster an einem '*', nicht an einem ';'? Auch der Vergleich mit .Contains muss doch i. allg. schief gehen, oder?
Du solltest tatsächlich RegEx nehmen - ersetze dafür '' durch '.'.
Hallo ujr,
ich trenne den String bei einem '*', da dieses ja alles mögliche an Zeichen sein kann.
Warum sollte Contains schief laufen? Also bei mir funktioniert das Ganze. Inzwischen habe ich noch ein paar kleine Ändernungen drinne, aber nichts Großes.
Mit Regex kenne ich mich gar nicht aus.. also muss ich ein ".txt" in "..txt" umwandeln? Un dann?
Gruß Dennis
Oh mann... wofür leicht wenn's auhc schwer geht..
Für alle die das gleiche "Problem" haben wie ich, vergesst den obigen Code, schaut euch diesen an:
private bool FileMatchFilter(string file, string filter, bool ignoreCase)
{
if (ignoreCase)
{
file = file.ToLower();
filter = filter.ToLower();
}
filter = filter.Replace("*", ".*");
Regex regex = new Regex(filter);
return regex.IsMatch(file);
}
ujr ich danke dir!
Gruß Dennis
Hallo,
ich trenne den String bei einem '*', da dieses ja alles mögliche an Zeichen sein kann.
Warum sollte Contains schief laufen? Also bei mir funktioniert das Ganze. Inzwischen habe ich noch ein paar kleine Ändernungen drinne, aber nichts Großes.Mit Regex kenne ich mich gar nicht aus.. also muss ich ein ".txt" in "..txt" umwandeln? Un dann?
Ah - ja. Jetzt hab' ich wohl Deinen Algorithmus richtig verstanden 🙂
Ich bin von Deinem Suchmuster "*.txt; .jpg" ausgegangen. Dieses müsste ja am ';' getrennt werden. Anschließend werden die einzelnen Suchmuster angewandt, so wie Du es schon gemacht hast.
.Contains hilft dann nicht, wenn die einzelnen Teilstrings im Zielstring in anderer Reihenfolge auftreten, also:
Muster: Teil1Teil2.txt
Dateiname: Teil3Teil2Teil1Teil0.txt
Zu den RegEx - Dein Beispiel ".txt" würde korrekterweise diesem RegEx entsprechen: "..txt", der '.' muss also noch als Sonderzeichen maskiert werden. Das beträfe natürlich auch andere Sonderzeichen wie runde und eckige Klammern. Schau Dir am besten dazu mal das RegEx-Tutorial im Artikel-Forum an.
Hallo ujr,
.Contains hilft dann nicht, wenn die einzelnen Teilstrings im Zielstring in anderer Reihenfolge auftreten, also:
Muster: Teil1Teil2*.txt
Dateiname: Teil3Teil2Teil1Teil0.txt
dazu sag ich nur folgendes:
Inzwischen habe ich noch ein paar kleine Ändernungen drinne
*grins*
der '.' muss also noch als Sonderzeichen maskiert werden
Das verstehe ich nicht. Warum muss der '.' als Sonderzeichen maskiert werden? Ein Punkt kann doch im jeden Dateinamen auftauchen.. ?
Das beträfe natürlich auch andere Sonderzeichen wie runde und eckige Klammern
Das wird nie passieren, weil der Methode nur gültige Dateinamen übergeben werden.
Gruß Dennis
Hallo,
der Punkt in einem RegEx steht für jedes beliebige Zeichen (oder auch keins). Wenn Du also tatsächlich einen Punkt haben möchtest, musst Du ihn im RegEx maskieren.
Runde und eckige Klammern sind in gültigen Dateinamen möglich und auch gar nicht so unwahrscheinlich. Da sie für RegEx eine besondere Bedeutung haben, müssen sie auch maskiert werden, wenn sie im Filterstring auftreten.
Hallo ujr,
achso okay. Das ist schlecht 🙂
Runde und eckige Klammern sind in gültigen Dateinamen möglich und auch gar nicht so unwahrscheinlich
Stimmt, hast Recht.
Ich werde mir das Ganze mal anschauen. Vielen Dank für deine Hilfe, hast mir sehr weitergeholfen!
Gruß Dennis
So, fertig:
private bool FileMatchFilter(string file, string filter, bool ignoreCase)
{
if (string.IsNullOrEmpty(file))
return true;
if (string.IsNullOrEmpty(filter))
return true;
if (ignoreCase)
{
file = file.ToLower();
filter = filter.ToLower();
}
if ((filter[0] != '*') && (!file.StartsWith(filter.Split('*')[0])))
return false;
if ((filter[filter.Length - 1] != '*') && (!file.EndsWith(filter.Split('*')[filter.Split('*').Length - 1])))
return false;
filter = filter.Replace("*", ".*");
filter = filter.Replace(".", "\\.");
filter = filter.Replace("(", "\\(");
filter = filter.Replace(")", "\\)");
filter = filter.Replace("[", "\\[");
filter = filter.Replace("]", "\\]");
Regex regex = new Regex(filter);
return regex.IsMatch(file);
}
🙂
Hallo dennisspohr,
filter = filter.Replace("*", ".*");
...
verwende besser Regex.Escape.
herbivore
Hallo herbivore,
habe ich gemacht 🙂
Danke!
Gruß Dennis