Matching subdirectory by comparing part of the directory path - c#

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?

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
}

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

Related

How combine two different Paths

I have two different Paths:
C:\Project\v4.0\Tool\Custom\CustomCompanyNames\Template\file\file.xml
C:\Destination\New\Place\Bin\Debug\output
I need a way two get values from two different paths
Expected Path:
C:\Destination\New\Place\Bin\Debug\output\CustomCompanyNames\file\file.xml
How can i solve it ?
Custom is a fix folder
All directories after Customs have different names
My Solution bad programmed:
Custom ist the first path
Destination the second path
private void test()
{
string result = destination;
string[] custom = customs.Split('\\');
foreach (var s in custom)
{
if(s.Contains("custom") || result.Contains("custom"))
{
if(s.Contains("templates")) break;
result = Path.Combine(result, s);
}
}
}
Instead of Splitting the path use IndexOf to find the Custom part and then Substring from it.
string path1 = #"C:\Project\v4.0\Tool\Custom\CustomCompanyNames\Template\file\file.xml";
string path2 = #"C:\Destination\New\Place\Bin\Debug\output";
string splitter = #"Custom\";
string desiredSection = path1.Substring(path1.IndexOf(splitter) + splitter.Length);
string output = Path.Combine(path2, desiredSection);

How to get double quotes around folder names with spaces

Here is my code
string path1 = #"C:\Program Files (x86)\Common Files";
string path2 = #"Microsoft Shared";
string path = Path.Combine(path1, path2);
Console.WriteLine(path);
The output provides me
C:\Program Files (x86)\Common Files\Microsoft Shared
I would like to have any folder names with spaces in double quotes as follows
C:\"Program Files (x86)"\"Common Files"\"Microsoft Shared"
How can I get that?
The easiest way to do this would be with LINQ.
You can split your folder path into an array listing all of the folder names, then manipulate each individual element using a Select().
In your case you would want to:
Split the string into an array (using the '/' to separate elements)
Format the folder name as "{folderName}" if the folder name contains spaces
Rejoin the array as a single string, with the '/' for your delimiter
Here is what that would look like, please note I have used 2 Select()'s for clarity & to help identify the different steps. They can be a single statement.
string path1 = #"C:\Program Files (x86)\Common Files";
string path2 = #"Microsoft Shared";
string path = System.IO.Path.Combine(path1, path2);
var folderNames = path.Split('\\');
folderNames = folderNames.Select(fn => (fn.Contains(' ')) ? String.Format("\"{0}\"", fn) : fn)
.ToArray();
var fullPathWithQuotes = String.Join("\\", folderNames);
The output of the above process is:
C:\"Program Files (x86)"\"Common Files"\"Microsoft Shared"
You can create an extension method
public static class Ex
{
public static string PathForBatchFile(this string input)
{
return input.Contains(" ") ? $"\"{input}\"" : input;
}
}
use it like
var path = #"C:\Program Files (x86)\Common Files\Microsoft Shared";
Console.WriteLine(path.PathForBatchFile());
It uses the string interpolation feature in C# 6.0. If you are not using C# 6.0 you can use this instead.
public static class Ex
{
public static string PathForBatchFile(this string input)
{
return input.Contains(" ") ? string.Format("\"{0}\"", input) : input;
}
}

Get Substring directory path not include first folder name in substring

Basically I want to sub-string directory path for example path is "server/student/personal/contact"
I want to path like "/student/personal/contact". That's mean first folder name I don't want to in
in path. Every time this path is change by project requirement so how to remove first folder name
from string path.
problem that here in string path first Folder name not same name every time So please help for this how to remove first folder name from string path
Try this:
string strp = "server/student/personal/contact";
strp = strp.Substring(strp.IndexOf("/"));
Output:
/student/personal/contact
I usually write something like this
string example = "server/student/personal/contact";
var paths = example.Split('/').ToList();
if (paths.Any())
{
paths.RemoveAt(0);
}
string result = string.Join("/", paths);
or you can:
string example = "server/student/personal/contact";
var pos = example.IndexOf("/", System.StringComparison.Ordinal);
if (pos > 0)
{
example = example.Substring(pos);
}
you can simply do this :
string path = "server/student/personal/contact";
//IndexOf() gives you the first occurrence of the character.
int firstSlash=path.IndexOf('/');
string modifiedPath = path.Substring(firstSlash);

How to remove characters in a string?

How to remove the some characters in a string ..
string s="testpage\information.xml"
I need only information.xml how to do that?
System.IO.Path may help you with this since the string contains a file path information. In your case, you may use Path.GetFileName(string path) to get the file name from a string.
Example
string s = #"testpage\information.xml";
string filename = Path.GetFileName(s);
//MessageBox.Show(filename);
Thanks,
I hope you find this helpful :)
Assuming the value that will be in s is always a file path, use the Path class to extract the file name
var filename = Path.GetFileName(s);
File path is of the form
aaaa\bbb\ccc\dddd\information.xml
To retrieve the last string, you can divide your string using the delimiter \
String path = #"aaaa\bbb\ccc\dddd\information.xml";
String a[] = path.Split('\\');
This will give String array as ["aaaa", "bbb", "ccc", "dddd", "information.xml"]
You can retrieve the filename as
String filename = a[a.Length-1];
If it is going to be a file path, then you can use the System.IO.Path class (MSDN) to extract the filename.
string s = "testpage\information.xml"
var filename = Path.GetFilename(s);
If it's always right of the backslash separator then you can use:
if (s.Contains(#"\"))
s= s.Substring(s.IndexOf(#"\") + 1);
Hope this is what you want:
var result=s.Substring(s.LastIndexOf(#"\") + 1);
If you are using file paths, see the Path.GetFileName Method
It will not check whether the file exists or not. So it will be faster.
s = Path.GetFileName(s);
If you need to check whether file exists, use File.Exists class.
Another way is to use String.Split() method
string[] arr = s.Split('\\');
if(arr.Length > 0)
{
s = arr[arr.Length - 1];
}
Another way is to use RegEx
s = Regex.Match(s, #"[^\\]*$").Value;
You can use the following line of codes to get file extension.
string filePath = #"D:\Test\information.xml";
string extention = Path.GetExtension(filePath);
If you need file name alone use,
string filePath = #"D:\Test\information.xml";
string filename = Path.GetFilename(filePath );
Use string.Replcae
string s = #"testpage\information.xml";
s = s.Replace(#"testpage\\",""); // replace 'testpage\' with empty string
You will get Output => s=information.xml
# is need only because you have backslash in your string
For further reading about STRING REPLACE
http://www.dotnetperls.com/replace
http://msdn.microsoft.com/en-us/library/system.string.replace.aspx
In C++ you can do something like this. Basically search for "/" or "\" from right to left of the path and crop the string starting from the first occurance of the delimiter:
string ExtractFileName(const string& strPathFileName)
{
size_t npos;
string strOutput = strPathFileName;
if(strPathFileName.rfind(L'/', npos) || strPathFileName.rfind(L'\\', npos))
{
strOutput = strPathFileName.substr(npos+1);
}
return strOutput;
}

In C# how can I prepare a string to be valid for windows directory name

I am writing a C# program which reads certain tags from files and based on tag values it creates a directory structure.
Now there could be anything in those tags,
If the tag name is not suitable for a directory name I have to prepare it to make it suitable by replacing those characters with anything suitable. So that directory creation does not fail.
I was using following code but I realised this is not enough..
path = path.replace("/","-");
path = path.replace("\\","-");
please advise what's the best way to do it..
thanks,
Import System.IO namespace and for path use
Path.GetInvalidPathChars
and for filename use
Path.GetInvalidFileNameChars
For Eg
string filename = "salmnas dlajhdla kjha;dmas'lkasn";
foreach (char c in Path.GetInvalidFileNameChars())
filename = filename.Replace(System.Char.ToString(c), "");
foreach (char c in Path.GetInvalidPathChars())
filename = filename.Replace(System.Char.ToString(c), "");
Then u can use Path.Combine to add tags to create a path
string mypath = Path.Combine(#"C:\", "First_Tag", "Second_Tag");
//return C:\First_Tag\Second_Tag
You can use the full list of invalid characters here to handle the replacement as desired. These are available directly via the Path.GetInvalidFileNameChars and Path.GetInvalidPathChars methods.
The characters you must now use are: ? < > | : \ / * "
string PathFix(string path)
{
List<string> _forbiddenChars = new List<string>();
_forbiddenChars.Add("?");
_forbiddenChars.Add("<");
_forbiddenChars.Add(">");
_forbiddenChars.Add(":");
_forbiddenChars.Add("|");
_forbiddenChars.Add("\\");
_forbiddenChars.Add("/");
_forbiddenChars.Add("*");
_forbiddenChars.Add("\"");
for (int i = 0; i < _forbiddenChars.Count; i++)
{
path = path.Replace(_forbiddenChars[i], "");
}
return path;
}
Tip: You can't include double-quote ("), but you can include 2 quotes ('').
In this case:
string PathFix(string path)
{
List<string> _forbiddenChars = new List<string>();
_forbiddenChars.Add("?");
_forbiddenChars.Add("<");
_forbiddenChars.Add(">");
_forbiddenChars.Add(":");
_forbiddenChars.Add("|");
_forbiddenChars.Add("\\");
_forbiddenChars.Add("/");
_forbiddenChars.Add("*");
//_forbiddenChars.Add("\""); Do not delete the double-quote character, so we could replace it with 2 quotes (before the return).
for (int i = 0; i < _forbiddenChars.Count; i++)
{
path = path.Replace(_forbiddenChars[i], "");
}
path = path.Replace("\"", "''"); //Replacement here
return path;
}
You'll of course use only one of those (or combine them to one function with a bool parameter for replacing the quote, if needed)
The correct answer of Nikhil Agrawal has some syntax errors.
Just for the reference, here is a compiling version:
public static string MakeValidFolderNameSimple(string folderName)
{
if (string.IsNullOrEmpty(folderName)) return folderName;
foreach (var c in System.IO.Path.GetInvalidFileNameChars())
folderName = folderName.Replace(c.ToString(), string.Empty);
foreach (var c in System.IO.Path.GetInvalidPathChars())
folderName = folderName.Replace(c.ToString(), string.Empty);
return folderName;
}

Categories

Resources