Hallo,
ich würde gerne Pfad strings mittels Regex matchen.
Ich suche nach allen zip Dateien die nicht in bestimmten Unterordnern liegen.
Hier ein Beispiel
string s = @"^(.*)(?!duNicht)(.*)\.zip*$";
bool a = Regex.IsMatch(@"\\10.249.161.2\Erwin\x.54.3\Franz\abc.zip", s);
bool b = Regex.IsMatch(@"\\10.249.161.2\Erwin\x.54.4\Franz\def.zip", s);
bool c = Regex.IsMatch(@"\\10.249.161.2\Erwin\x.54.5\duNicht\Franz\ghi.zip", s);
bool d = Regex.IsMatch(@"\\10.249.161.2\Erwin\x.54.6\Franz\jkl.zip", s);
bool e = Regex.IsMatch(@"\\10.249.161.2\Erwin\x.54.7\duNicht\Franz\mno.zip", s);
Meine Erwartungshaltung wäre nun dass a,b und d true wären und c und e false.
Allerdings sind alle true.
Bin für jede Hilfe Dankbar.
Auch für Regex-Strings ist das Escape-Zeichen relevant 😉
[Artikel] Regex-Tutorial
[FAQ] Was bedeutet das @ (=at) vor String-Literalen? Und: Wissenswertes zu Escape-Sequenzen
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hi Yedigun,
das Problem ist, dass der Regex wirklich überall matcht. Hier ein Beispiel für Fall (c):
Group[0] = "\\10.249.161.2\E" // (.*)
Group[1] = "" // (?!duNicht)
Group[2] = "rwin\x.54.5\duNicht\Franz\ghi.zip" // (.*)\.zip*$
Übrigens akzeptierst du auch die Endungen .zi, .zip, .zipp, zippp, zippp (wahrscheinlich nicht gewollt 😉 ).
Du musst es andersherum aufziehen. Erstelle einen Regex, der matcht, wenn es ein ungültiger Pfad ist!
Im übrigen kannst du auch ohne Regex vorankommen:
string[] directories = mypath.Split(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries);
bool valid = ! Array.Exists(directories, dir => dir == "duNicht");
beste Grüße
zommi
Hallo Yedigun,
obwohl ich zommi darin zustimme, dass es einfacher und verständlicher ist, die Negation auf C#-Ebene vorzunehmen, allerdings schon gerne angewendet auf eine Regex-Lösung:
bool a = !Regex.IsMatch (input, @"\\duNicht\\");
kann man die Negation durchaus auf Regex-Ebene vornehmen. Der Knackpunkt ist, dass der Verzeichnisname an keiner Stelle vorkommen darf. Dein Pattern prüft nur, dass es mindestens eine beliebige Stelle gibt, an der er nicht vorkommt.
Die tatsächlich gewünschte Prüfung kann man entweder vermischt mit dem eigentlichen Match vornehmen:
bool a = Regex.IsMatch (input, @"^(?:(?!\\duNicht\\).)*\.zip$");
oder einmal zu Anfang separat prüfen:
bool a = Regex.IsMatch (input, @""^(?!.*\\duNicht\\).*\.zip$");
Bei der Prüfung, dass ein Muster an keiner Stelle vorkommen darf, muss man immer höllisch aufpassen, was man in die Gruppierungsklammern einschließt und was nicht und worauf genau man die Quantifizierer anwendet. Zum Beispiel würde der folgende Pattern nur prüfen, dass "duNicht" nur am Anfang des Strings nicht vorkommt und wäre daher für deinen Einsatzzweck unbrauchbar:
bool a = Regex.IsMatch (input, @"^(?:(?!\\duNicht\\).*)\.zip$"); // falsch
BTW: Ich habe überall \\duNicht\\
verwendet, denn der Pattern ja soll nur Unterverzeichnisse mit dem Namen duNicht ausschließen, und keine Dateien, die so heißen, und wohl auch keine Dateien und Verzeichnisse, die duNicht nur als Teil enthalten.
herbivore