Reputation: 29876
Say I have the following path, which we will call the "base":
C:\my\dir
and these two other paths, which we will call paths "A" and "B" respectively:
C:\my\dir\is\a\child
C:\not\my\dir
Obviously, the base must be a directory for this to make any sense. Path A is inside the base at some arbitrary depth, and Path B is not inside base at all. Paths A and B could be files or directories; it really doesn't matter.
How can I detect that Path A is inside base and Path B is not? Preferably, we could avoid directly messing with the strings to do this.
The case of the following path has come to my attention:
C:\my\dir2\child
At the moment, the proposed solutions all result in a false positive in this case, but the solution should be able to distinguish. I think this kind of thing is why I was concerned about doing this via string manipulation/comparison directly. What would be the most effective way of dealing with this?
Additionally, I don't want to make any assumptions about whether the base path does or does not contain a trailing directory separator.
Upvotes: 1
Views: 167
Reputation: 68263
There's this: (Edited to allow for specifying a base path with or without a trailing backslash)
$basepath = 'C:\my\dir'
$patha = 'C:\my\dir\is\a\child'
$pathb = 'C:\not\my\dir'
$pathc = 'C:\my\dir2\child'
$patha -like "$($basepath.trim('\'))\*"
$pathb -like "$($basepath.trim('\'))\*"
$pathc -like "$($basepath.trim('\'))\*"
True
False
False
Upvotes: 1
Reputation: 24071
This is a case of text/pattern matching, so regex works fine.
PS C:\> $base = "^"+[regex]::escape('C:\my\dir')+".*`$"
PS C:\> $base
^C:\\my\\dir.*$
PS C:\> "C:\my\dir\is\a\child" -match $base
True
PS C:\> "C:\not\my\dir" -match $base
False
The regex ^C:\\my\\dir.+$
looks for start ^
, followed by string literal (handily escaped with [regex]::escape()
) that is the base path and finally anything until end: .*$
.
Edit:
To handle the commented case, just add backslash to base dir like so,
PS C:\> $base = "^"+[regex]::escape('C:\my\dir\')+".*`$"
PS C:\> $base
^C:\\my\\dir\\.*$
PS C:\> "C:\my\dir\is\a\child" -match $base
True
PS C:\> "C:\not\my\dir" -match $base
False
PS C:\> "C:\my\dir2\child" -match $base
False
Upvotes: 1
Reputation: 5899
In .NET, path is simply a string. You have static System.IO.Path
class that works with strings and returns paths as a strings too.
So, in this terms, I would define pathA
as a child of pathB
as simple as following:
bool child = pathA.StartsWith(pathB, StringComparison.OrdinalIgnoreCase);
Upvotes: 3