Splitting strings with slashes in C# - c#

I have the following types of strings. One with three slashes and one with two:
a) filepath = "/F00C/Home/About"
b) filepath = "/Administration/Menus"
What I need to do is a function that will allow me to get the values of "home" and "administration" and put into topMenu variable and get the values of "Menus" and "About" and put this into the subMenu variable.
I am familiar with the function slashes = filePath.Split('/'); but my situation is not so simple as there are the two types of variables and in both cases I just need to get the last two words.
Is there a simple way that I could make the Split function work for both without anything to complex?

What's wrong with something like this ?
var splits = filePath.Split('/');
var secondLast = splits[splits.Length-2];
var last = splits[splits.Length-1];
Remarks:
Any check on the length of splits array (that must be >= 2) is missing.
Also, this code works only with forward-slash ('/'). To support both backslash and forward-slash separators, have a look at #Saeed's answer

Am I'm missing something or you just want:
var split = filepath.Split('/');
var last = split[split.Length -1];
var prev = split[split.Length -2];

var items = filePath.Split('/');
first = items[items.Length - 2];
second = items[items.Length - 1];
Also if this is a actual path you can use Path:
var dir = Path.GetDirectoryName(filePath);
dir = Path.GetFileName(dir);
var file = Path.GetFileName(filePath);
Edit: I edited Path version as the way discussed my digEmAll.

Related

Double separator in the path after Path.GetDirectoryName method c#

I want get directory from blob absolute Uri:
https://001.blob.core.windows.net/files/11-files.trg.
For this I use Path.GetDirectoryName method. As result I have:
https:\\001.blob.core.windows.net\\files.
Why does a double separator appear and how to replace it with a single one?
I think Path.GetDirectoryName only works for relative paths, but not for URLs. So the first thing that comes to my mind is something like this:
var url = "https://001.blob.core.windows.net/files/11-files.trg";
var temp = new string(url.ToCharArray().Reverse().ToArray());
int index = temp.IndexOf('/');
temp = temp.Substring(index + 1 , temp.Length - index - 1);
var result = new string(temp.ToCharArray().Reverse().ToArray());
Console.WriteLine(result);
//output: https://001.blob.core.windows.net/files

Can I shorten this code with a loop in C#?

I have this code written in C# but looks kind of "bad" and I would like to shorten it somehow and keep it clean and simple.
All this code works pretty fine but I want to know if there's any other way I can achieve the same thing.
EDIT: I forgot to mention that the firstLine has a bad date format attached with it, so it is like this: "This_is_my_first_line_20220126". So I split the string and then only join it with the corrected date. The problem is that I can never know how long the new string would be and I don't want to handle the code like this and go up to 100 parts.
Here's my code:
string correctDate = "26012022";
string[] lines = File.ReadAllLines("text.txt");
string firstLine = lines.FirstOrDefault();
//note: firstLine looks like this: This_is_my_first_line_20220126
string[] sub = firstLine.Split('_');
string name="";
if(sub.Length==2)
name = sub[0]+"_"+sub[1]+"_"+correctDate;
else if(sub.Length==3)
name = sub[0]+"_"+sub[1]+"_"+sub[2]+"_"correctDate;
...
else if(sub.Length==20)
name = sub[0]+"_"+ ... "_" + sub[19];
Now, my final name value should be "This_is_my_line_26012022" but I want it to depend on the length of the given string. So far I know that the maximum length would go up to 20 but I don't want my code to look like this. Can I shorten it somehow?
you can find the LastIndexOf the underscore and drop the date by using Substring:
string firstLine = "This_is_my_first_line_20220126";
string correctDate = "26012022";
string correctString = firstLine.Substring(0, firstLine.LastIndexOf("_") + 1) + correctDate;
Still a little perplexed with the split aproach, but this a way to join back all elements
string name = string.Join("_", sub.Take(sub.Length - 1).Append(correctDate));
Or use the substring method (and no need of all that split & join)
name = firstLine.Substring(0, firstLine.LastIndexOf("_") +1) + correctDate;
I forgot to mention that firstLine has a bad date format like "This_is_my_Line_20220125"
If you want to correct just the first line:
string correctDate = "26012022";
string[] lines = File.ReadAllLines("text.txt");
lines[0] = lines[0][..^8] + correctDate;
[..^8] uses C# 9's "indices and ranges" feature, that allows for a more compact way of taking a substring. It means "from the start of the string, up to the index 8 back from the end of the string".
If you get a wiggly line and possibly a messages like "... is not available in C# version X" you can use the older syntax, which would be more like lines[0] = lines[0].Remove(lines[0].Length - 8) + correctDate;
If you want to correct all lines:
string correctDate = "26012022";
string[] lines = File.ReadAllLines("text.txt");
for(int x = 0; x < lines.Length; x++)
lines[x] = lines[x][..^8] + correctDate;
If the incorrect date isn't always 8 characters long, you can use LastIndexOf('_') to locate the last _, and snip it to that point

C# read path withoutI put / in each subfolder

I want to put file path in File.Copy(path)
How can I put the path and not add / every time?
In python I can put r to read the path and not add /:
open(r"path")
Is there anything similar in C Sharp?
Yes you can use the # operator: var path = #"c:\\APath\bier";
these are called verbatim strings:
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/strings/#regular-and-verbatim-string-literals
Edit:
Also when dealing with paths string interpolation may come in handy, in short its a way to substitute values in a string. Its the same as string.format but the syntax is better imo:
var hello = "Hello";
var world = "world";
var helloworldStringFormat = string.Format("{0} {1}", hello, world);
var helloworldStringInterpolation = $"{hello} {world}";
Also see: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/strings/#string-interpolation
Any ways you can do things like this:
var someValue = "bier";
var path3 = $"c:\\APath\\{someValue}";
var path4 = string.Format(#"c:\APath\{0}", someValue);
Also check out the Path class for dealing with paths, and optionally the Directory class.
https://learn.microsoft.com/en-us/dotnet/api/system.io.path?view=net-5.0
https://learn.microsoft.com/en-us/dotnet/api/system.io.directory?view=net-5.0

Remove characters after specific character in string, then remove substring?

I feel kind of dumb posting this when this seems kind of simple and there are tons of questions on strings/characters/regex, but I couldn't find quite what I needed (except in another language: Remove All Text After Certain Point).
I've got the following code:
[Test]
public void stringManipulation()
{
String filename = "testpage.aspx";
String currentFullUrl = "http://localhost:2000/somefolder/myrep/test.aspx?q=qvalue";
String fullUrlWithoutQueryString = currentFullUrl.Replace("?.*", "");
String urlWithoutPageName = fullUrlWithoutQueryString.Remove(fullUrlWithoutQueryString.Length - filename.Length);
String expected = "http://localhost:2000/somefolder/myrep/";
String actual = urlWithoutPageName;
Assert.AreEqual(expected, actual);
}
I tried the solution in the question above (hoping the syntax would be the same!) but nope. I want to first remove the queryString which could be any variable length, then remove the page name, which again could be any length.
How can I get the remove the query string from the full URL such that this test passes?
For string manipulation, if you just want to kill everything after the ?, you can do this
string input = "http://www.somesite.com/somepage.aspx?whatever";
int index = input.IndexOf("?");
if (index >= 0)
input = input.Substring(0, index);
Edit: If everything after the last slash, do something like
string input = "http://www.somesite.com/somepage.aspx?whatever";
int index = input.LastIndexOf("/");
if (index >= 0)
input = input.Substring(0, index); // or index + 1 to keep slash
Alternately, since you're working with a URL, you can do something with it like this code
System.Uri uri = new Uri("http://www.somesite.com/what/test.aspx?hello=1");
string fixedUri = uri.AbsoluteUri.Replace(uri.Query, string.Empty);
To remove everything before the first /
input = input.Substring(input.IndexOf("/"));
To remove everything after the first /
input = input.Substring(0, input.IndexOf("/") + 1);
To remove everything before the last /
input = input.Substring(input.LastIndexOf("/"));
To remove everything after the last /
input = input.Substring(0, input.LastIndexOf("/") + 1);
An even more simpler solution for removing characters after a specified char is to use the String.Remove() method as follows:
To remove everything after the first /
input = input.Remove(input.IndexOf("/") + 1);
To remove everything after the last /
input = input.Remove(input.LastIndexOf("/") + 1);
Here's another simple solution. The following code will return everything before the '|' character:
if (path.Contains('|'))
path = path.Split('|')[0];
In fact, you could have as many separators as you want, but assuming you only have one separation character, here is how you would get everything after the '|':
if (path.Contains('|'))
path = path.Split('|')[1];
(All I changed in the second piece of code was the index of the array.)
The Uri class is generally your best bet for manipulating Urls.
To remove everything before a specific char, use below.
string1 = string1.Substring(string1.IndexOf('$') + 1);
What this does is, takes everything before the $ char and removes it. Now if you want to remove the items after a character, just change the +1 to a -1 and you are set!
But for a URL, I would use the built in .NET class to take of that.
Request.QueryString helps you to get the parameters and values included within the URL
example
string http = "http://dave.com/customers.aspx?customername=dave"
string customername = Request.QueryString["customername"].ToString();
so the customername variable should be equal to dave
regards
I second Hightechrider: there is a specialized Url class already built for you.
I must also point out, however, that the PHP's replaceAll uses regular expressions for search pattern, which you can do in .NET as well - look at the RegEx class.
you can use .NET's built in method to remove the QueryString.
i.e., Request.QueryString.Remove["whatever"];
here whatever in the [ ] is name of the querystring which you want to
remove.
Try this...
I hope this will help.
You can use this extension method to remove query parameters (everything after the ?) in a string
public static string RemoveQueryParameters(this string str)
{
int index = str.IndexOf("?");
return index >= 0 ? str.Substring(0, index) : str;
}

How to cut a string

I have a strings like
"/LM/W3SVC/1216172363/root/175_Jahre_STAEDTLER_Faszination_Schreiben"
And I need only "175_Jahre_STAEDTLER_Faszination_Schreiben" where "root" is separator. How can I do this?
"/LM/W3SVC/1216172363/root/175_Jahre_STAEDTLER_Faszination_Schreiben".Split("/root/")[1] should give you "175_Jahre_STAEDTLER_Faszination_Schreiben"
Another method:
String newstring = file_path.Substring(file_path.LastIndexOf('/') + 1);
Check out the System.IO.Path methods - not quite files and folders but with the / delimiter it just might work!
If you're looking to extract a part of a string based on an overall pattern, regular expressions can be a good alternative in some situations.
string s = "/LM/W3SVC/1216172363/root/175_Jahre_STAEDTLER_Faszination_Schreiben";
Regex re = new Regex(#"/root/(?<goodPart>\w+)$");
Match m = re.Match(s);
if (m.Success) {
return m.Groups["goodPart"].ToString();
}
string s = "/LM/W3SVC/1216172363/root/175_Jahre_STAEDTLER_Faszination_Schreiben";
string separator = "root";
string slash = "/";
int idx = s.IndexOf(separator);
string result = s.SubString(idx + separator.Length + slash.Length);
Use String.Split to separate the string with "root" as the separator. Then use the second element of the resulting array.
If you need to find a relative path based on a base path (which it sounds like what the problem you are trying to solve is, or at least a generalization of your problem) you can use the System.Uri class. It does have it's limitations, however. The cleanest and most correct way to find a relative path is to use DirectoryInfo. With DirectoryInfo you can "walk" the directory tree (backwards or forwards) and build a hierarchy based on that. Then just do a little set manipulation to filter out duplicates and what you have left is your relative path. There are some details, like adding ellipses in the correct place, etc..., but DirectoryInfo is a good place to start in order to parse paths based on the current OS platform.
FYI - I just finished writing a component here at work to do just that so it's fairly fresh in my mind.
string s = "/LM/W3SVC/1216172363/root/175_Jahre_STAEDTLER_Faszination_Schreiben";
int li = s.LastIndexOf("root/");
s = s.Substring(li + 5, s.Length - 1 - (li + 4));
MessageBox.Show(s);

Categories

Resources