How do get the first occurrence of a char in Substring - c#

I'm trying to get the first occurrence in my substring start point:
string dir = Request.MapPath(Request.ApplicationPath) + "\\App_GlobalResources\\";
foreach (var file in Directory.EnumerateFiles(dir, "*.resx"))
{
ddlResources.Items.Add(new ListItem { Text = file.Substring(firstoccuranceof("."), file.LastIndexOf(".")), Value = file });
}
if I do file.Substring(file.IndexOf("."), file.LastIndexOf(".")) I get an error

To answer your actual question - you can use string.IndexOf to get the first occurrence of a character. Note that you'll need to subtract this value from your LastIndexOf call, since Substring's second parameter is the number of characters to fetch, not a start and end index.
However... Instead of parsing the names, you can just use Path.GetFilenameWithoutExtension to get the filename directly.

First occurence
String.IndexOf('.')
Last occurence
String.LastIndexOf('.')

Use IndexOf and LastIndexOf string methods to get index of first and last occurrence of "search" string. You may use System.IO.Path.GetExtension(), System.IO.Path.GetFileNameWithoutExtension(), and System.IO.Path.GetDirectoryName() methods to parse the path.
For instance,
string file = #"c:\csnet\info.sample.txt";
Console.WriteLine(System.IO.Path.GetDirectoryName(file)); //c:\csnet
Console.WriteLine(System.IO.Path.GetFileName(file)); //info.sample.txt
Console.WriteLine(System.IO.Path.GetFileNameWithoutExtension(file));//info.sample
Console.WriteLine(System.IO.Path.GetExtension(file)); //.txt

file.IndexOf(".")
Should get you the first occurence of ".". Otherwise it will return -1 if not found.

I think that in your particular case you are NOT trying to get IndexOf... Instead you need to use 0 because you are trying to create a key based on filename if understand correctly:
`ddlResources.Items.Add(new ListItem(file.Substring(0, file.LastIndexOf(".")), file ));`
Also, you have '{}' in there as in new ListItem { ... } which is also going to cause a syntax error... Anyhow have a look..

Because the original question is marked with the [regex] tag, I'll provide the following solution, however the best answer for simple parsing of paths using .NET is not by regex.
//extracts "filename" from "filename.resx"
string name = Regex.Match("filename.resx", #"^(.*)\..+?$").Groups[1].Value;
Use an answer that relies on the Path class instead, for simplicity. Other answers contain that info.

Here you go!)
Using a string variable type
int index = str.IndexOf(#"\");
"C:\Users\somebody\Desktop\aFolder\someFile"
https://www.peachpit.com/articles/article.aspx?p=31938&seqNum=12#:~:text=To%20find%20the%20first%20or,string%20you%20are%20searching%20for.

Related

C# Request path comparison with router path

I'm trying to compare below two strings using c# asp.net core. The motivation is to compare two paths except path parameter (without manually splitting and comparing one by one). Is it possible to do this in single line using any in-build method?
Requested: /api/v1/schedules/S210715001/comments
Original: /api/v1/schedules/{id}/comments
Thanks in advance.
You could create a regex pattern of the original string containing curly brackets and then match against the requested string.
string original = #"/api/v1/schedules/{id}/comments";
string requested = #"/api/v1/schedules/S210715001/comments";
string originalPattern = Regex.Replace(original, #"\{[^\}]*\}", #"\w*");
var isMatch = Regex.Match(requested, $"^{originalPattern}$", RegexOptions.IgnoreCase).Success;
There is a built-in fuction called Path.GetFileName in System.IO allowing you to extract a file name from a whole path.
Here is how to use it:
var original = "/api/v1/schedules/S210715001/comments";
var requested = "api/v1/schedules/{id}/comments";
Console.WriteLine("original: " + Path.GetFileName(original));
Console.WriteLine("requested: " + Path.GetFileName(requested));
output:
original: comments
requested: comments
Note : there are some subtilities on what is considered a directory separator : backslash, forward slash etc. (see here), but I think it's easier to use than regular expressions.

How to include ":" in a filepath if Spit(':') is used in C#

I have an application where I have to provide number of parameters in the format Name:Value
I provide the list of parameters through the Command line arguments value under "Debug" section of the project
So, it look something like that: "MyJobName" "0" "#FullFilePath:C:\MyFile.txt" "#FileType:MyFileType" "#FileDate:20200318" "#FileID:MyAppID"
One parameter is FilePath:C:\FileDir\MyFileTxt.txt
So, when the following logic is applied:
for (int i = 2; i <= args.GetLength(0) - 1; i++)
{
L.Add(args[i].Split(':')[0], args[i].Split(':')[1]);
}
My Parameter looks like that: FilePath:C, ignoring the rest of the path.
The final parameter list that I need to pass to the Stored Procedure should have "Name:Value" format
How can I fix that?
Split lets you pass the maximum array length.
See Split Split(Char[], Int32)
Splits a string into a maximum number of substrings based on the characters
in an array.
You also specify the maximum number of substrings to return.
Sample:
var keyValue = args[i].Split(new char[]{ ':' }, 2);
L.Add(keyValue[0], keyValue[1]);
This way only the first : is taken. The other : that come after it are ignored and will be part of the second item in the array.
But I honestly advise you to use a proper parameter parser, because your approach is very easy to break and very very fragile.
https://github.com/commandlineparser/commandline
Have a look at dragonfruit and Systel.CommandLine
Instead of writing your arguments parser yourself.
It’s a way to have type safe arguments in your main method.
Scott Hanselman has a great blog post about it.
The great part being your XML comments are used to generate a help message.
The moment you use Split, you exclude the delimiter from being a valid character without having to add the extra overloads to it. So if you absolutely must use a colon as your delimiter, you can either use the Split with overload as suggested above, or write extra code to address it;below is how I would parse it.
Of course, a much easier alternative (if possible) would be to change your delimiter to something you know it would never use, something like a pipe or a tilde or a backtick (|, ~, ). Then Split would work cleanly.
"#FullFilePath:C:\MyFile.txt" "#FileType:MyFileType" "#FileDate:20200318" "#FileID:MyAppID"
If your parameters always have the format #ParameterName:ParameterValue, your best bet is to parse the command line args like so:
var argumentsList = new Dictionary<string,object>();
for (int i=2; i < args.Length; i++)
{
int colonIndex = args[i].IndexOf(":");
string parameterName = args[i].Substring(0, colonIndex - 1);
string parameterValue = args[i].Substring(colonIndex + 1);
argumentsList[parameterName] = parameterValue;
}
The scope of your question centers around how to get around the colon, so however you choose to store the parameter values is up to you, I just used the dictionary as an example to help wrap up the code.
This will skip FilePath and give you C:\FileDir\MyFileTxt.txt
string.Join(":", args[i].Split(':').Skip(1));

Wrong result when Split a string when the given characters are not found

When I tried to split a string value of some text here with ++. I expected the result to be an empty list. Since the ++ is not found in the string some text here, the result of a Count on the List should be 0.
However, the result I get is 1 (when I Count on the List).
How am I able to determine if the string has no ++ in it ? (a Count did not work)
List<string> l = value.Split("++").ToList();
The observed behavior is by design. If delimiter is not found a collection with a single item is returned. As documentation states:
If this instance does not contain any of the characters in separator, the returned array consists of a single element that contains this instance.
If you want to check if delimiter exists you can use .Contains("++") or .IndexOf("++") != -1
By default, if no matches are found it returns the string in a array of size one.
How am I able to determine if the string has no ++ in it ?
if (value.Contains("++"))
edit: wow a bunch of answers already while i was writing this. :D
As #Gilad and others have pointed out, this is indeed the expected output. If a string does not contain the split value, the entire string is returned as the first item in the list.
If you plan on using this split value later, you can still use the .Split() method to determine if your split string is contained within the string, by simply checking if the count is equal to 1:
List<string> l = value.Split(new[] {"++"}).ToList();
if (l.Count == 1) {
//++ was not found in the string
} else {
//++ was found in the string (l.Count-1) times
}
Note of caution: It's less efficient to split a string, and allocate an array, than simply just checking with a method such as .Contains(). Use the above solution, if you may actually use the above split items later in the code.
If there is no "++" in the string, you get back the original string. If there are n "++"'s in the string, you get n+1 splits returned. You code is fine except that it needs an array passed:
var l = value.Split(new string[] {"++"}, StringSplitOptions.None).ToList();
So when l.Count() == 1 then there is no "++" in the string

about string removing in C#

Whats is correct to do?
check if exists, then remove?
var input = "foo #main baa";
if(input.Contains("#main")) {
input = input.Replace("#main", "");
}
or just:
input = input.Replace("#main", "");
Well, this seem a simple question,but I really want know.
Thanks in advance.
The Contains check actually just makes your code slower.
Remove it.
The Contains call needs to loop through the string until it finds #main.
The Replace call then needs to do the same exact loop (it can't remember it from the Contains call).
This is a Shlemiel the Painter's algorithm.
Replace can handle strings with zero or more occurrences of the search string, so you don't need the check.
Just do the replacement - if it's not there, nothing should happen.
Just make the call to Replace(). If the substring isn't found nothing happens and you avoid an additional call to Contains().
I would do this:
input = input.Replace("#main", "").Replace(" "," ");
To remove any double spaces.
Just remove it. The only thing to check is if the string is null or not.

Select last element quickly after a .Split()

I have this code :
stringCutted = myString.Split("/"). // ???
and I'd like to store in stringCutted the last element of the string[] after the split, directly, quickly, without storing the splitted array in a variable and access to that element with array[array.length].
Is this possible in C#?
If you're using .NET 3.5 or higher, it's easy using LINQ to Objects:
stringCutted = myString.Split('/').Last();
Note that Last() (without a predicate) is optimized for the case where the source implements IList<T> (as a single-dimensional array does) so this won't iterate over the whole array to find the last element. On the other hand, that optimization is undocumented...
stringCutted=myString.Split("/").Last()
But, just FYI, if you're trying to get a filename from a path, this works heaps better:
var fileName=System.IO.Path.GetFileName("C:\\some\path\and\filename.txt");
// yields: filename.txt
Since you want a solution that returns the last element directly, quickly, without store the splitted array, i think this may be useful:
stringCutted = myString.Substring(myString.LastIndexOf("/")+1);
Use LINQ
"t/e/s/t".Split("/").Last();
For using this code, I skip last element from the Url link.
string url = Request.Url.ToString().Substring(0, Request.Url.ToString().LastIndexOf('/'));
For Addition:
When string format like 'a/b/c/d' then
yourstring.Split("/").Last();
When string format like \head_display\27_[Item A]\head_image\original_image\1_Item A.png
yourstring.Split("\\").Last();
first '\' actually to skip second '\'

Categories

Resources