TtT23
TtT23

Reputation: 7030

Matching subdirectory by comparing part of the directory path

I probably didn't word the title too well but hopefully my explanation should illustrate the problem.

Basically, I have to find out the names of the subdirectories excluding the file name when given another path to compare with. For instance,

Given: "C:\Windows\System32\catroot\sys.dll"

Compare: "C:\Windows"

Matched String: "\System32\catroot"

Here's another example:

Given: "C:\Windows\System32\WindowsPowerShell\v1.0\Examples\profile.ps1"

Compare: "C:\Windows\System32"

Matched String: "\WindowsPowerShell\v1.0\Examples"

What would be the best way to perform this matching?

Upvotes: 2

Views: 761

Answers (2)

Steve
Steve

Reputation: 216293

There is no need to use Regex.
This could be easily done using string.StartsWith, string.Substring and Path.GetDirectoryName to remove the filename.

string fullPath = @"C:\Windows\System32\WindowsPowerShell\v1.0\Examples\profile.ps1"; 
string toMatch = @"C:\Windows\System32";
string result = string.Empty;
if(fullPath.StartsWith(toMatch, StringComparison.CurrentCultureIgnoreCase) == true)
{
    result = Path.GetDirectoryName(fullPath.Substring(toMatch.Length));
} 
Console.WriteLine(result);

EDIT: this changes take care of the observation from aiodintsov and include the idea from @Joe about non-canonical or partial path names

string fullPath = @"C:\Windows\System32\WindowsPowerShell\v1.0\Examples\profile.ps1"; 
string toMatch = @"C:\Win";

string result = string.Empty;
string temp = Path.GetDirectoryName(Path.GetFullPath(fullPath));
string[] p1 = temp.Split('\\');
string[] p2 = Path.GetFullPath(toMatch).Split('\\');
for(int x = 0; x < p1.Length; x++)
{
   if(x >= p2.Length || p1[x] != p2[x]) 
             result = string.Concat(result, "\\", p1[x]);
}

In this case I assume that the partial match should be considered as no match. Also take a look at the answer from @Joe for the problem of partial or non-canonical paths

Upvotes: 0

to StackOverflow
to StackOverflow

Reputation: 124706

You might also want to consider special cases such as:

  • Relative paths

  • Paths with short names such as C:\PROGRA~1 for C:\Program Files

  • Non-canonical paths (C:\Windows\System32\..\..\file.dat)

  • Paths that use an alternate separator (/ instead of \)

One way is to convert to a canonical full path using Path.GetFullPath before comparing

E.g.

string toMatch = @"C:\PROGRA~1/";
string path1 = @"C:/Program Files\Common Files\..\file.dat";
string path2 = @"C:\Program Files\Common Files\..\..\file.dat";

string toMatchFullPath = Path.GetFullPath(toMatch);
string fullPath1 = Path.GetFullPath(path1);
string fullPath2 = Path.GetFullPath(path2);

// fullPath1 = C:\Program Files\file.dat
// toMatchFullPath = C:\Program Files\
if (fullPath1.StartsWith(toMatchFullPath, StringComparison.OrdinalIgnoreCase))
{
    // path1 matches after conversion to full path
}

// fullPath2 = C:\file.dat
// toMatchFullPath = C:\Program Files\
if (fullPath2.StartsWith(toMatchFullPath, StringComparison.OrdinalIgnoreCase))
{
    // path2 does not match after conversion to full path
}

Upvotes: 4

Related Questions