Laden...

Mit RegEx String ohne Vorkommen eines Wortes matchen

Letzter Beitrag vor 9 Jahren 4 Posts 1.562 Views
Mit RegEx String ohne Vorkommen eines Wortes matchen

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.

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