4

The regex pattern I wrote below is matching the string before "FinalFolder". How can I get the folder name (in this case "FinalFolder") just after the string matching the regex?

EDIT : Pretty sure I got my Regex wrong. My intent was to match upto "C:\FolderA\FolderB\FolderC\FolderD\Test 1.0\FolderE\FolderF" and then find the folder after that. So, in this case, the folder I am looking for is "FinalFolder"

    [TestMethod]
    public void TestRegex()
    {
        string pattern = @"[A-Za-z:]\\[A-Za-z]{1,}\\[A-Za-z]{1,}\\[A-Za-z0-9]{1,}\\[A-Za-z0-9]{1,}\\[A-Za-z0-9._s]{1,}\\[A-Za-z]{1,}\\[A-Za-z]{1,}";
        string textToMatch = @"C:\FolderA\FolderB\FolderC\FolderD\Test 1.0\FolderE\FolderF\FinalFolder\Subfolder\Test.txt";
        string[] matches = Regex.Split(textToMatch, pattern);
        Console.WriteLine(matches[0]);
    }
Ashish Gupta
  • 14,869
  • 20
  • 75
  • 134
  • 1
    Your regex seems to be matching the entire string, not just the string before "FinalFolder." – Chris Berger Jun 16 '17 at 21:15
  • See https://stackoverflow.com/questions/674479/how-do-i-get-the-directory-from-a-files-full-path – Wiktor Stribiżew Jun 16 '17 at 21:18
  • Sorry - I am looking for the folder which is after the matching string. Not the parent folder of the file. Sorry again, I updated the question. – Ashish Gupta Jun 16 '17 at 21:21
  • 1
    The pattern doesn't match the string. Did you get it to match? –  Jun 16 '17 at 21:22
  • Pretty sure I got my Regex wrong. My intent was to match upto "C:\FolderA\FolderB\FolderC\FolderD\Test 1.0\FolderE\FolderF" and then find the folder after that. – Ashish Gupta Jun 16 '17 at 21:28
  • 1
    I would use a Substring. Something like `textToMatch.Substring(textToMatch.IndexOf(matches[0]) + matches[0].Length)`. Once you have that substring, you can match up to the first slash in it. – Chris Berger Jun 16 '17 at 21:30
  • 1
    Overall, I think that Regex is the wrong tool for this job, but whatever. – Chris Berger Jun 16 '17 at 21:31
  • Your regex still matches the whole string. – Deadzone Jun 16 '17 at 21:32
  • 1
    You can do it a couple of ways depending on what's known about the path. If the level is fixed `^(?:[^\\]*\\){level}(.*)$`, if the name is fixed `^(?:[^\\]*\\)*FolderF\\(.*)$` I guess that is the only way. –  Jun 16 '17 at 21:33
  • Or, if you just want the from _last folder_ on, it would be this `(?<=\\|^)[^\\]*\\[^\\]*$` –  Jun 16 '17 at 21:39

3 Answers3

3

There are plenty of other hints and advice that will lead you to getting the desired folder and I recommend considering them. But since it looks like you would still benefit from learning more regex skills, here is the answer you asked for: Getting non-matching part of string.

Let's imagine that your Regex actually matched the given path, for instance a pattern like: [A-Za-z]:\\[A-Za-z]+\\[A-Za-z]+\\[A-Za-z0-9]+\\[A-Za-z0-9]+\\[A-Za-z0-9._\s]+\\[A-Za-z]+\\[A-Za-z]+

You could get the matched string, its position and length, then determine where in the original source string the next folder name would start. But then you would also need to determine where the next folder name ends.

MatchCollection matches = Regex.Matches(textToMatch, pattern);
if (matches.Count > 0 ) {
    Match m = matches[0];
    var remaining = textToMatch.Substring(m.Index + m.Length);
    //Now find the next backslash and grab the leftmost part...
}

That answers your most general question, but that approach defeats the entire utility of using regex. Instead, just extend your pattern to match the next folder!

Regex patterns already provide the ability to capture certain portions of a match. The default regex construct for capturing text is a set of parenthesis. Even better, .Net regex supports named capture groups using (?<name>).

//using System.Text.RegularExpressions;

string pattern = @"(?<start>"  
        + @"[A-Za-z]:\\[A-Za-z]+\\[A-Za-z]+\\[A-Za-z0-9]+\\[A-Za-z0-9]+\\[A-Za-z0-9._\s]+\\[A-Za-z]+\\[A-Za-z]+" 
        + @")\\(?<next>[A-Za-z0-9._\s]+)(\\|$)";
string textToMatch = @"C:\FolderA\FolderB\FolderC\FolderD\Test 1.0\FolderE\FolderF\FinalFolder\Subfolder\Test.txt";

MatchCollection matches = Regex.Matches(textToMatch, pattern);
if (matches.Count > 0 ) {
    var nextFolderName = matches[0].Groups["next"];
    Console.WriteLine(nextFolderName);
}
C Perkins
  • 3,733
  • 4
  • 23
  • 37
0

As posted in a comment, your regex seems to be matching the entire string. But in this particular case, since you are dealing with a filename, I would use FileInfo.

FileInfo fi = new FileInfo(textToMatch);
Console.WriteLine(fi.DirectoryName);
Console.WriteLine(fi.Directory.Name);

DirectoryName will be the full path, while Directory.Name will be just the subfolder in question.

Chris Berger
  • 557
  • 4
  • 14
  • Sorry - I am looking for the folder which is after the matching string. Not the parent folder of the file. Sorry again, I updated the question. – Ashish Gupta Jun 16 '17 at 21:21
0

So, using FileInfo, something like this?

(new FileInfo(textToMatch)).Directory.Parent.Name
NetMage
  • 26,163
  • 3
  • 34
  • 55