Splitting a long string in c# - c#

I have this string and I need it split multiple ways.
Pending order
Sell EUR/USD
Price 1.0899
Take profit at 1.0872
Stop loss at 1.0922
From 23:39 18-01-2016 GMT Till 03:39 19-01-2016 GMT
That is the full string i need to split it as such
string SellorBuy = "Sell";
string Price = "1.0889";
string Profit = "1.0872";
string StopLoss = "1.0922";
The Numbers are different every-time but i still need them to be split into there own strings. I have no idea how to go about this. Any help would be greatly appreciated!
What I've tried
string message = messager.TextBody;
message.Replace(Environment.NewLine, "|");
string[] Spliter;
char delimiter = '|';
Spliter = message.Split(delimiter);
It didn't seem to add the "|" to it.

Split the string on newlines then process each line based on the first word of that line. More info on splitting on newlines here... https://stackoverflow.com/a/1547483/4322803
// Split the string on newlines
string[] lines = theText.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
// Process each line
foreach(var line in lines){
var words = line.Split(' ');
var firstWord = parts[0];
switch (firstWord){
case "Price":
Price = words[1];
break;
case "Take":
Profit = words[words.Length - 1];
break;
// etc
}
}
The code above is really just to get you started. You should probably create a class called PendingOrder with strongly typed properties for Price, Profit etc (e.g. use float or decimal for the numbers rather than strings) and pass the raw text in via the constructor to populate the properties.

Related

Sorting a given string - What is wrong with my IF Contains block?

Super new to C# apologize upfront. My goal is to sort a given string. Each word in the string will contain a single number. This number is the position the word should have in the result. Numbers can be from 1 to 9. So 1 will be the first word (not 0).
My plan of attack is to split the string, having one variable of int data-type (int lookingForNum) and the other variable turning that into a String data-type(string stringLookingForNum), then for each loop over the array looking to see if any elements contain string stringLookingForNum, if they do I add it to an emptry string variable, lastly add 1 to int variable lookingForNum. My issue seems to be with the if statement with the Contains method. It will not trigger the way I currently have it written. Hard coding in if (word.Contains("1")) will trigger that code block but running it as written below will not trigger the if statement.Please can anyone tell my WHY!?!? I console.log stringLookingForNum and it is for sure a string data type "1"
This noobie would appreciate any help. Thanks!
string testA = "is2 Thi1s T4est 3a"; //--> "Thi1s is2 3a T4est"
string[] arrayTestA = testA.Split(' ');
string finalString = string.Empty;
int lookingForNum = 1; //Int32
foreach (string word in arrayTestA){
string stringLookingForNum = lookingForNum.ToString();
//Don't understand why Contains is not working as expected here)
if (word.Contains(stringLookingForNum)){
finalString = finalString + $"{word} ";
}
lookingForNum++;
}
you need this - look for the string with 1, the look for the string with 2 etc. Thats not what you are doing
you look at the first string and see if it contains one
then look at the second one and see if it contains 2
....
int lookingForNum = 1;
while(true){ // till the end
string stringLookingForNum = lookingForNum.ToString();
bool found = false;
foreach (string word in arrayTestA){
if (word.Contains(stringLookingForNum)){
finalString = finalString + $"{word} ";
found = true;
break;
}
}
if(!found) break;
lookingForNum++;
}
To sort you should simply use OrderBy, and since you need to sort by number inside a word - just Find and extract a number from a string
string testA = "is2 Thi1s T4est 3a";
var result = testA.Split().OrderBy(word =>
Int32.Parse(Regex.Match(word, #"\d+").Value));
Console.WriteLine(string.Join(" ", result));

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.

Getting the last part of elements when splitting a string

Here's what I'm trying to workout split function.
The com is a string passed from a textbox, and it removes the first piece from the text.
The text in the textbox is being pass as this ".fedex TYU-123 Time to pick up package"
Then, when gms is part of the first piece of the strip[] array.
string format = com.Remove(0,1);
string[] strip = format.Split(new string[] { " " }, StringSplitOptions.None);
if (strip[0] == "gsm")
{
string carrier = strip[0];
string trackid = strip[1];
string message = strip[2];
}
strip[2] only contains "Time". I wanted to return the last part as this: "Time to pick up package".
Keep in mind also, since the message will be different at times as well, so I don't want a specific string search.
How can I achieve this?
It sounds like you only want to split the first three elements.
Split() has an overload that lets you tell it how many items to return:
format.Split(new[] { ' ' }, 3)
I assume you want all words starting with the third, use string.Join(" ", strip.Skip(2)):
string[] strip = format.Split(new string[] { " " }, StringSplitOptions.None);
if (strip[0] == "gsm")
{
string carrier = strip[0];
string trackid = strip[1];
string message = string.Join(" ", strip.Skip(2)); //Time to pick up package
}
You can use the string.Split(char[], int32) method for this, in which you can give a max. number of splitted strings to return.
So:
format.Split(new[] {' '}, 3);
would do the trick.
More info: http://msdn.microsoft.com/en-us/library/c1bs0eda.aspx

Unable to Split the string accordingly

I know this question would have been asked infinite number of times, but I'm kinda stuck.
I have a string something like
"Doc1;Doc2;Doc3;12"
it can be something like
"Doc1;Doc2;Doc3;Doc4;Doc5;56"
Its like few pieces of strings separated by semicolon, followed by a number or id.
I need to extract the number/id and the strings separately.
To be exact, I can have 2 strings: one having "Doc1;Doc2;Doc3" or "Doc1;Doc2;Doc3;Doc4" and the other having just the number/id as "12" or "34" or "45" etc.
And yeah I am using C# 3.5
I understand its a pretty easy and witty question, but this guy is stuck.
Assistance required from experts.
Regards
Anurag
string.LastIndexOf and string.Substring are the keys to what you're trying to do.
var str = "Doc1;Doc2;Doc3;12";
var ind = str.LastIndexOf(';');
var str1 = str.Substring(0, ind);
var str2 = str.Substring(ind+1);
One way:
string[] tokens = str.Split(';');
var docs = tokens.Where(s => s.StartsWith("Doc", StringComparison.OrdinalIgnoreCase));
var numbers = tokens.Where(s => s.All(Char.IsDigit));
String docs = s.Substring(0, s.LastIndexOf(';'));
String number = s.Substring(s.LastIndexOf(';') + 1);
One possible approach would be this:
var ids = new List<string>();
var nums = new List<string>();
foreach (var s in input.Split(';'))
{
int val;
if (!int.TryParse(s, out val)) { ids.Add(s); }
else { nums.Add(s); }
}
where input is something like Doc1;Doc2;Doc3;Doc4;Doc5;56. Now, ids will house all of the Doc1 like values and nums will house all of the 56 like values.
you can use StringTokenizer functionality.
http://www.c-sharpcorner.com/UploadFile/pseabury/JavaLikeStringTokenizer11232005015829AM/JavaLikeStringTokenizer.aspx
split string using ";"
StringTokenizer st = new StringTokenizer(src1,";");
collect final String. that will be your ID.
You may try one of two options: (assuming your input string is in string str;
Approach 1
Get LastIndexOf(';')
Split the string based on the index. This will give you string and int part.
Split the string part and process it
Process the int part
Approach 2
Split the string on ;
Run a for loop - for (int i = 0; i < str.length - 2; i++) - this is the string part
Process str[length - 1] separately - this is the int part
Please take this as a starting point as there could be other approaches to implement a solution for this
string actual = "Doc1;Doc2;Doc3;12";
int lstindex = actual.LastIndexOf(';');
string strvalue = actual.Substring(0, lstindex);
string id = actual.Substring(lstindex + 1);

Splitting a string which contain multiple symbols to get specific values

I cannot believe I am having trouble with this following string
String filter = "name=Default;pattern=%%;start=Last;end=Now";
This is a short and possibly duplicate question, but how would I split this string to get:
string Name = "Default";
string Pattern = "%%" ;
string start = "Last" ;
string end = "Now" ;
Reason why I ask is my deadline is very soon, and this is literally the last thing I must do. I'm Panicking, and I'm stuck on this basic command. I tried:
pattern = filter.Split(new string[] { "pattern=", ";" },
StringSplitOptions.RemoveEmptyEntries)[1]; //Gets the pattern
startDate = filter.Split(new string[] { "start=", ";" },
StringSplitOptions.RemoveEmptyEntries)[1]; //Gets the start date
I happen to get the pattern which I needed, but as soon as I try to split start, I get the value as "Pattern=%%"
What can I do?
Forgot to mention
The list in this string which needs splitting may not be in any particular order . this is a single sample of a string which will be read out of a stringCollection (reading these filters from Properties.Settings.Filters
Using string.Split this is a two stage process.
In the first case split on ; to get an array of keyword and value pairs:
string[] values = filter.Split(';');
Then loop over the resultant list splitting on = to get the keywords and values:
foreach (string value in values)
{
string[] pair = value.Split('=');
string key = pair[0];
string val = pair[1];
}
String filter = "name=Default;pattern=%%;start=Last;end=Now";
string[] temp = filter.Split('=');
string name = temp[1].Split(';')[0];
string pattern = temp[2].Split(';')[0];
string start = temp[3].Split(';')[0];
string end = temp[4].Split(';')[0];
This should do the trick:
string filter = "name=Default;pattern=%%;start=Last;end=Now";
// Make a dictionary.
var lookup = filter
.Split(';')
.Select(keyValuePair => keyValuePair.Split('='))
.ToDictionary(parts => parts[0], parts => parts[1]);
// Get values out of the dictionary.
string name = lookup["name"];
string pattern = lookup["pattern"];
string start = lookup["start"];
string end = lookup["end"];
The start date ends up at the thrird position in the array:
startDate = filter.Split(new string[] { "start=", ";" }, StringSplitOptions.RemoveEmptyEntries)[2];
Instead of splitting the string once for each value, you might want to split it into the separate key-value pairs, then split each pair:
string[] pairs = filter.Split(';');
string[] values = pairs.Select(pair => pair.Split('=')[1]).ToArray();
string name = values[0];
string pattern = values[1];
string start = values[2];
string end = values[3];
(This code of course assumes that the key-value pairs always come in the same order.)
You could also split the string into intersperced array, so that every other item is a key or a value:
string[] values = filter.Split(new string[] { "=", ";" }, StringSplitOptions.None);
string name = values[1];
string pattern = values[3];
string start = values[5];
string end = values[7];
Edit:
To handle key-values in any order, make a lookup from the string, and pick values from it:
ILookup<string, string> values =
filter.Split(';')
.Select(s => s.Split('='))
.ToLookup(p => p[0], p => p[1]);
string name = values["name"].Single();
string pattern = values["pattern"].Single();
string start = values["start"].Single();
string end = values["end"].Single();
You can use SingleOrDefault if you want to support values being missing from the string:
string name = values["name"].SingleOrDefault() ?? "DefaultName";
The lookup also supports duplicate key-value pairs. If there might be duplicates, just loop through the values:
foreach (var string name in values["name"]) {
// do something with the name
}
Well I tried something like this:
var result = "name=Default;pattern=%%;start=Last;end=Now".Split(new char[]{'=',';'});
for(int i=0;i<result.Length; i++)
{
if(i%2 == 0) continue;
Console.WriteLine(result[i]);
}
and the output is:
Default
%%
Last
Now
Is this what you want?
You see, the thing is now that your Split on filter a second time still starts from the beginning of the string, and it matches against ;, so since the string hasn't changed, you still retrieve previous matches (so your index accessor is off by X).
You could break this down into it's problem parts, such that:
var keyValues = filter.Split(';');
var name = keyValues[0].Split('=')[1];
var pattern = keyValues[1].Split('=')[1];
var start = keyValues[2].Split('=')[1];
var end = keyValues[3].Split('=')[1];
Note that the above code is potentially prone to error, and as such should be properly altered.
You can use the following:
String filter = "name=Default;pattern=%%;start=Last;end=Now";
string[] parts = filter.Split(';');
string Name = parts[0].Substring(parts[0].IndexOf('=') + 1);
string Pattern = parts[1].Substring(parts[1].IndexOf('=') + 1);
string start = parts[2].Substring(parts[2].IndexOf('=') + 1);
string end = parts[3].Substring(parts[3].IndexOf('=') + 1);
Use this:
String filter = "name=Default;pattern=%%;start=Last;end=Now";
var parts = filter.Split(';').Select(x => x.Split('='))
.Where(x => x.Length == 2)
.Select(x => new {key = x[0], value=x[1]});
string name = "";
string pattern = "";
string start = "";
string end = "";
foreach(var part in parts)
{
switch(part.key)
{
case "name":
name = part.value;
break;
case "pattern":
pattern = part.value;
break;
case "start":
start = part.value;
break;
case "end":
end = part.value;
break;
}
}
If you don't need the values in named variables, you only need the second line. It returns an enumerable with key/value pairs.
My solution has the added benefits that the order of those key/value pairs in the string is irrelevant and it silently ignores invalid parts instead of crashing.
I found a simple solution on my own too. Most of your answers would have worked if the list would have been in the same order every single time, but it wont be. the format however, will always stay the same. The solution is a simple iteration using a foreach loop, and then checking if it starts with a certain word, namely, the word I am looking for, like Name, Pattern etc.
Probably not the most cpu efficient way of doing it, but it is C# for dummies level. Really brain-fade level.
Here is my beauty.
foreach (string subfilter in filter.Split(';')) //filter.Split is a string [] which can be iterated through
{
if (subfilter.ToUpper().StartsWith("PATTERN"))
{
pattern = subfilter.Split('=')[1];
}
if (subfilter.ToUpper().StartsWith("START"))
{
startDate = subfilter.Split('=')[1];
}
if (subfilter.ToUpper().StartsWith("END"))
{
endDate = subfilter.Split('=')[1];
}
}

Categories

Resources