Extracting first token from a delimeted string - c#

i have a string:
e.g. WORD1_WORD2_WORD3
how do i get just WORD1 from the string?
i.e the text before the first underscore

It may be tempting to say Split - but that involves the creating of an array and lots of individual strings. IMO, the optimal way here is to find the first underscore, and take a substring:
string b = s.Substring(0, s.IndexOf('_')); // assumes at least one _
(edit)
If you are doing this lots, you could add some extension methods:
public static string SubstringBefore(this string s, char value) {
if(string.IsNullOrEmpty(s)) return s;
int i = s.IndexOf(value);
return i > 0 ? s.Substring(0,i) : s;
}
public static string SubstringAfter(this string s, char value) {
if (string.IsNullOrEmpty(s)) return s;
int i = s.IndexOf(value);
return i >= 0 ? s.Substring(i + 1) : s;
}
then:
string s = "a_b_c";
string b = s.SubstringBefore('_'), c = s.SubstringAfter('_');

YOUR_STRING.Split('_')[0]
In fact the Split method returns an array of strings resulting from splitting the original string at any occurrence of the specified character(s), not including the character at which the split was performed.

if s is the string:
int idx = s.IndexOf('_');
if (idx >= 0)
firstPart = s.Substring(0,idx);

("WORD1_WORD2_WORD3").Split('_')[0]
should return "WORD1". If it doesn't work try .Spilt() on a string variable with the Content you specified.
string str="WORD1_WORD2_WORD3";
string result=str.Split('_')[0];
This actually returns an array:
{"WORD1", "WORD2", "WORD3"}

There are several ways. You can use Split, Substring. etc. An example with Split:
String var = "WORD1_WORD2_WORD3";
String result = var.Split('_')[0];

Related

Cannot get a proper ToTitleCase

I've tried three approaches to get a ProperName solution for a string of all CAPS.
Here is my code:
string testStr = "SYNDEGAARD";
string result1 = UppercaseFirst(testStr);
string titleCase = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(testStr);
string result2 = titleCase;
CultureInfo culture_info = Thread.CurrentThread.CurrentCulture;
TextInfo text_info = culture_info.TextInfo;
string result3 = text_info.ToTitleCase(testStr);
private static string UppercaseFirst(string s)
{
// Check for empty string.
if (string.IsNullOrEmpty(s))
{
return string.Empty;
}
// Return char and concat substring.
return char.ToUpper(s[0]) + s.Substring(1);
}
All three results are "SYNDENGAARD". It never changes to "Syndengaard".
The reason why you can't get the result you wanted is because ToTitleCase() doesn't work if the input string is all in capital letters.
You can try changing SYNDEGAARD to SYNDEGAARDx and see the difference.
As to why that's the default behavior I am not sure.
Also you forgot to add ToLower() in this function to make sure that the preceding texts will be in lowercase.
private static string UppercaseFirst(string s)
{
// Check for empty string.
if (string.IsNullOrEmpty(s))
{
return string.Empty;
}
// Return char and concat substring.
return char.ToUpper(s[0]) + s.Substring(1).ToLower(); // Missing ToLower()
}
EDIT:
Here's why nothing happens for uppercase texts.
TextInfo.ToTitleCase Method (String).
Converts the specified string to title case (except for words that are
entirely in uppercase, which are considered to be acronyms).
Use Humanizer, it will provide you with the range of utilities for conversions and manipulate strings, enums, dates, times, timespans, numbers and quantities.
https://github.com/Humanizr/Humanizer
Nuget Package
https://www.nuget.org/packages/Humanizer/
Var name = "shyam bhagat";
var titleCase = name.Humanize(LetterCasing.Title);
Just update to this
return char.ToUpper(s[0]) + s.Substring(1).ToLower();

Remove parts of string

I have the following string
string a = #"\\server\MainDirectory\SubDirectoryA\SubdirectoryB\SubdirectoryC\Test.jpg";
I'm trying to remove part of the string so in the end I want to be left with
string a = #"\\server\MainDirectory\SubDirectoryA\SubdirectoryB";
So currently I'm doing
string b = a.Remove(a.LastIndexOf('\\'));
string c = b.Remove(b.LastIndexOf('\\'));
Console.WriteLine(c);
which gives me the correct result. I was wondering if there is a better way of doing this? because I'm having to do this in a fair few places.
Note: the SubdirectoryC length will be unknown. As it is made of the numbers/letters a user inputs
There is Path.GetDirectoryName
string a = #"\\server\MainDirectory\SubDirectoryA\SubdirectoryB\SubdirectoryC\Test.jpg";
string b = Path.GetDirectoryName(Path.GetDirectoryName(a));
As explained in MSDN it works also if you pass a directory
....passing the returned path back into the GetDirectoryName method will
result in the truncation of one folder level per subsequent call on
the result string
Of course this is safe if you have at least two directories level
Heyho,
if you just want to get rid of the last part.
You can use :
var parentDirectory = Directory.GetParent(Path.GetDirectoryName(path));
https://msdn.microsoft.com/de-de/library/system.io.directory.getparent(v=vs.110).aspx
An alternative answer using Linq:
var b = string.Join("\\", a.Split(new string[] { "\\" }, StringSplitOptions.None)
.Reverse().Skip(2).Reverse());
Some alternatives
string a = #"\\server\MainDirectory\SubDirectoryA\SubdirectoryB\SubdirectoryC\Test.jpg";
var b = Path.GetFullPath(a + #"\..\..");
var c = a.Remove(a.LastIndexOf('\\', a.LastIndexOf('\\') - 1));
but I do find this kind of string extensions generally usefull:
static string beforeLast(this string str, string delimiter)
{
int i = str.LastIndexOf(delimiter);
if (i < 0) return str;
return str.Remove(i);
}
For such repeated tasks, a good solution is often to write an extension method, e.g.
public static class Extensions
{
public static string ChopPath(this string path)
{
// chopping code here
}
}
Which you then can use anywhere you need it:
var chopped = a.ChopPath();

Extract string parts that are separated with commas

I need to extract a string into 3 different variables.
The input from the user will be in this format 13,G,true.
I want to store the number in an integer, the "G" in a character and "true" into a string.
But I don't know how to specify the comma location so the characters before or after the comma can be stored in another variable.
I'm not allowed to use the LastIndexOf method.
string msg = "13,G,true";
var myArray = msg.Split(",");
// parse the elements
int number;
if (!Int32.TryParse(myArray[0], out number) throw new ArgumentException("Whrong input format for number");
string letter = myArray[1];
string b = myArry[2];
// or also with a boolean instead
bool b;
if (!Int32.TryParse(myArray[2], out b) throw new ArgumentException("Whrong input format for boolean");
use String.Split
string str='13,G,true';
string[] strArr=str.Split(',');
int32 n=0,intres=0;
char[] charres = new char[1];
string strres="";
if(!Int32.TryParse(strArr[0], out n))
{
intres=n;
}
if(strArr[0].length>0)
{
charres[0]=(strArr[1].toString())[0];
}
strres=strArr[2];
//you'll get 13 in strArr[0]
//you'll get Gin strArr[1]
//you'll get true in strArr[2]
var tokens = str.Split(","); //Splits to string[] by comma
var first = int32.Parse(tokens[0]); //Converts first string to int
var second = tokens[1][0]; //Gets first char of the second string
var third = tokens[2];
But be aware, that you also need to validate the input
You are going to need method String.Split('char'). This method splits string using specified char.
string str = "13,G,true";
var arrayOfStrings=str.Split(',');
int number = int.Parse(arrayOfStrings[0]);
// original input
string line = "13,G,true";
// splitting the string based on a character. this gives us
// ["13", "G", "true"]
string[] split = line.Split(',');
// now we parse them based on their type
int a = int.Parse(split[0]);
char b = split[1][0];
string c = split[2];
If what you are parsing is CSV data, I would check out CSV parsing libraries related to your language. For C#, Nuget.org has a few good ones.

Efficient way to get part of a string

I have a name which is made of a prefix a type and name , i want to retrieve the name part.
Prefix always remains same but Type can change.
I have the following code to get the name part:
string prefix = "Prefix-";
string str =prefix + "Type-hello-j---.xml";
str = Path.GetFileNameWithoutExtension(str);
str = str.Substring(prefix.Length);
str = str.Substring(str.IndexOf('-') + 1);
In the above example the name part is: hello-j---
Is there any efficient/better way to do the same in C# ?
You can use an overload of string.Split() that lets you specify the number of parts:
string fileName = "Prefix-Type-hello-j---.xml";
string withoutExtension = Path.GetFileNameWithoutExtension(str);
var parts = str.Split(new[]{'-'}, 3);
string name = parts[2];
If this is always the structure of your string, this would work :
string name = str.Split(new[]{'-'})[2];
I'm assuming you only want "hello". If you want the rest of the name you could use the overloaded method as #KingCronus suggested :
string name = str.Split(new[]{'-'}, 3)[2];
You can also create an extension function that works like String.IndexOf but that gets the position of the nth occurrence of the specified character:
public static int IndexOfWithCount(this string input, char character, int occurenceNumber)
{
int count = 0;
for (int numCaracter = 0; numCaracter < input.Length; numCaracter++)
if (input[numCaracter] == character)
{
count++;
if (count == occurenceNumber)
return numCaracter;
}
return -1;
}
To use it:
string nameWithoutExt = Path.GetFileNameWithoutExtension(str);
string result = nameWithoutExt.Substring(nameWithoutExt.IndexOfWithCount('-', 2) + 1);
It depends how you define efficient but if lines of code fits your defintion how about:
var str = "prefix-Type-hello-j---.xml";
var name = Regex.Match(str, #"(.+?-)(.+?-)(?<name>.+)\.").Groups["name"].Value;
The first two capturing groups consume the prefix and the the type then the namedgroup consumes the name until the extension starts.
This code assumes there is always a match, if there is not it will throw a nullreference exception.
See Regex.Match

How to change one string from definite position using other string?

I have two strings
string str1 = "Hello World !"; // the position of W character is 6
string str2 = "peace";
//...
string result = "Hello peace !"; // str2 is written to str1 from position 6
Is there a function like this:
string result = str1.Rewrite(str2, 6); // (string, position)
EDITED
This "Hello World !" is just an example, I don't know whether there is "W" character in this string, what I only know are: str1, str2, position (int)
There is not, but you could create one using an extension method.
public static class StringExtensions
{
public static string Rewrite(this string input, string replacement, int index)
{
var output = new System.Text.StringBuilder();
output.Append(input.Substring(0, index));
output.Append(replacement);
output.Append(input.Substring(index + replacement.Length));
return output.ToString();
}
}
Then, the code you posted in your original question would work:
string result = str1.Rewrite(str2, 6); // (string, position)
#danludwigs answer is better from a code understandability perspective, however this version is a tad faster. Your explanation that you are dealing with binary data in string format (wtf bbq btw :) ) does mean that speed might be of the essence. Although using a byte array or something might be better than using a string :)
public static string RewriteChar(this string input, string replacement, int index)
{
// Get the array implementation
var chars = input.ToCharArray();
// Copy the replacement into the new array at given index
// TODO take care of the case of to long string?
replacement.ToCharArray().CopyTo(chars, index);
// Wrap the array in a string represenation
return new string(chars);
}
There is many way to do this...
Because I'm a lazy ass, I would go:
result = str1.Substring(0, 6) + str2 + str1.Substring(12, 2);
or
result = str1.Replace("World", str2);
My advice would be, in Visual Studio, right click on "string" and select "Go To Definition". You will see all the methods available to the string "class".

Categories

Resources