C# - Convert string, to a two dimensional string array - c#

I can't seem to figure this out.
I want to convert this:
string foobarString = "[['Foo', 'bar'], ['Foo', 'bar'], ['Foo', 'bar']]";
To a two dimensional array (or list) so it looks like this:
fooBarArray[0] = Array['Foo', "bar"];
fooBarArray[1] = Array['Foo', "bar"];
fooBarArray[2] = Array['Foo', "bar"];
... etc.
I have tried spliting by ("],") and then cleaning the string and creating an array afterwards. But it's just to damn UGLY!
I want a cleaner version. Is there no method built in for such a method in C#?
// Thanks

Since your question is not giving us enough information I will assume that you are trying to convert some JSON into an array of strings.
As far as I know there is no build in method in C# for this.
You could use an extension for this. Newtonsoft JSON
After installing this package you will be able to use the following code:
string foobarString = "[['Foo', 'bar'], ['Foo', 'bar'], ['Foo', 'bar']]";
var result = Newtonsoft.Json.JsonConvert.DeserializeObject<string[][]>(foobarString);

First, split it by "[[", "], [", "]]"
var array1 = foobarString.Split(new string[] {"[[", "], [", "]]"}, StringSplitOptions.RemoveEmptyEntries);
array1 will contain "'Foo', 'bar'", "'Foo', 'bar'", "'Foo', 'bar'"
Then you can split every element by ','
var fooBarArray = array1.Select(x => x.Split(',').ToArray()).ToArray()
You can do it in one line
var fooBarArray = foobarString.Split(new string[] { "[[", "], [", "]]" }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Split(',').ToArray()).ToArray()

You could use Regex to get the array elements from your source string and then convert the matches into your arrays. Something like this should do the trick:
var input = "[['Foo', 'bar'], ['Foo', 'bar'], ['Foo', 'bar']]";
// search for [' more than one word character, put them into group a ',
// more than one whitespace ' more than one word character, put them into group b ']
var arrayMatches = Regex.Matches(input, #"\['(?<a>[\w]+)',\s+'(?<b>[\w]+)'\]");
var arrays = new List<string[]>();
foreach (Match arrayMatch in arrayMatches)
{
// if the match was unsuccessful, take the next match
if(!arrayMatch.Success)
continue;
// create a new string array with element in group a as first element and the element in groub b as the second one
var array = new [] {arrayMatch.Groups["a"].Value, arrayMatch.Groups["b"].Value};
arrays.Add(array);
}
// convert list to array
return arrays.ToArray();

{
const string oldString = "[['Foo', 'bar'], ['Foo', 'bar'], ['Foo', 'bar']]";
var list = Newtonsoft.Json.JsonConvert.DeserializeObject<List<List<string>>>(oldString);
}

There you can find some examples. The String.Split function returns an array so you can do
string[] lines = foobarString.Split(new char[]{']'}, StringSplitOptions.RemoveEmtpyEntries);
fooBarArray[0] = lines[i].Split(new char[]{'[',']', ','}, StringSplitOptions.RemoveEmtpyEntries);
Take a look at this thread: multidimensional-array-vs

Related

How to parse a text file and find a string between two other

For example, let's say I have this:
string test = "id:test THISISTHESTRINGIWANT id2:test"
And I want to get THISISTHESTRINGIWANT. In order to do that I was wondering if its possible to find it like this:
left_string = "id:test ", right_string = " id2"
Thank You
You can use the .split like this
string test = "id:test THISISTHESTRINGIWANT id2:test"
char[] delimiterChars = { ' '};
string[] output= test.Split(delimiterChars);
this will give you 3 strings {id:test,THISISTHESTRINGIWANT,id2:test}
you can then iterate through the string array with whatever condition you want to weed out the unwanted data or you can change the char array to include any characters you want to split on.

string.split based on nth position of comma in c#

I have string:
string string1 = "0,11,22,33,5500,2000,9800,10,10,10,10,10,10,10,10,10,10,";
Now I have to split this string from 4th position of comma. I need to get values 5500,2000,9800 separately.
How can I split my string like this?
You can use LINQ and Skip:
var array = string1.Split(',').Skip(4).ToArray();
If you want to limit the elements of array (just want to get the 3 values):
var array = string1.Split(',').Skip(4).Take(3).ToArray();
I assume you don't know LINQ, so rember to import namespaces in order to use LINQ extension methods (if not imported):
using System.Linq;
EDIT (see comments):
var splitted = string1.Split(',');
var firstArr = splitted.Take(4);
var secondArray = splitted.Skip(4).Take(3);
var thirdArray = splitted.Skip(7);
If you want to have them like a string:
var s1 = string.Join(",", firstArray);
var s2 = string.Join(",", secondArray);
var s3 = string.Join(",", thirdArray);
.Why don't you do it like this:
string string1 = "0,11,22,33,5500,2000,9800,10,10,10,10,10,10,10,10,10,10,";
string[] parts = string1.Split(',');
As the OP asked a follow up question here is his answer:
To join the parts do it like this:
string firstPart = string.Join(",",parts.Take(4));
string secondPart = string.Join(",",parts.Skip(4).Take(3));
string thirdPart= string.Join(",",parts.Skip(7));

Splitting data with Regex (Regular Expressions)

I would need some help with matching data in this example string:
req:{REQUESTER_NAME},key:{abc},act:{UPDATE},sku:{ABC123,DEF-123},qty:{10,5}
Essentially, every parameter is separated by "," but it is also included within {} and I need some help with regex as I am not that good with it.
Desired Output:
req = "REQUESTER_NAME"
key = "abc"
act = "UPDATE"
sku[0] = "ABC123"
sku[1] = "DEF-123"
qty[0] = 10
qty[1] = 5
I would suggest you do the following
Use String Split with ',' character as the separator (eg output req:{REQUESTER_NAME})
With each pair of data, do String Split with ';' character as the separator (eg output "req", "{REQUESTER_NAME}")
Do a String Replace for characters '{' and '}' with "" (eg output REQUESTER_NAME)
Do a String Split again with ',' character as separator (eg output "ABC123", "DEF-123")
That should parse it for you perfectly. You can store the results into your data structure as the results come in. (Eg. You can store the name at step 2 whereas the value for some might be available at Step 3 and for others at Step 4)
Hope That Helped
Note:
- If you don't know string split - http://www.dotnetperls.com/split-vbnet
- If you don't know string replace - http://www.dotnetperls.com/replace-vbnet
The below sample may helps to solve your problem. But here lot of string manipulations are there.
string input = "req:{REQUESTER_NAME},key:{abc},act:{UPDATE},sku:{ABC123,DEF-123},qty:{10,5}";
Console.WriteLine(input);
string[] words = input.Split(new string[] { "}," }, StringSplitOptions.RemoveEmptyEntries);
foreach (string item in words)
{
if (item.Contains(':'))
{
string modifiedString = item.Replace(",", "," + item.Substring(0, item.IndexOf(':')) + ":");
string[] wordsColl = modifiedString.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string item1 in wordsColl)
{
string finalString = item1.Replace("{", "");
finalString = finalString.Replace("}", "");
Console.WriteLine(finalString);
}
}
}
First, use Regex.Matches to get the parameters inside { and }.
string str = "req:{REQUESTER_NAME},key:{abc},act:{UPDATE},sku:{ABC123,DEF-123},qty:{10,5}";
MatchCollection matches = Regex.Matches(str,#"\{.+?\}");
string[] arr = matches.Cast<Match>()
.Select(m => m.Groups[0].Value.Trim(new char[]{'{','}',' '}))
.ToArray();
foreach (string s in arr)
Console.WriteLine(s);
output
REQUESTER_NAME
abc
UPDATE
ABC123,DEF-123
10,5
then use Regex.Split to get the parameter names
string[] arr1 = Regex.Split(str,#"\{.+?\}")
.Select(x => x.Trim(new char[]{',',':',' '}))
.Where(x => !string.IsNullOrEmpty(x)) //need this to get rid of empty strings
.ToArray();
foreach (string s in arr1)
Console.WriteLine(s);
output
req
key
act
sku
qty
Now you can easily traverse through the parameters. something like this
for(int i=0; i<arr.Length; i++)
{
if(arr1[i] == "req")
//arr[i] contains req parameters
else if(arr1[i] == "sku")
//arr[i] contains sku parameters
//use string.Split(',') to get all the sku paramters and process them
}
Kishore's answer is correct. This extension method may help implement that suggestion:
<Extension()>
Function WideSplit(InputString As String, SplitToken As String) As String()
Dim aryReturn As String()
Dim intIndex As Integer = InputString.IndexOf(SplitToken)
If intIndex = -1 Then
aryReturn = {InputString}
Else
ReDim aryReturn(1)
aryReturn(0) = InputString.Substring(0, intIndex)
aryReturn(1) = InputString.Substring(intIndex + SplitToken.Length)
End If
Return aryReturn
End Function
If you import System.Runtime.CompilerServices, you can use it like this:
Dim stringToParse As String = "req:{REQUESTER_NAME},key:{abc},act:{UPDATE},sku:{ABC123,DEF-123},qty:{10,5}"
Dim strTemp As String
Dim aryTemp As String()
strTemp = stringToParse.WideSplit("req:{")(1)
aryTemp = strTemp.WideSplit("},key:{")
req = aryTemp(0)
aryTemp = aryTemp(1).WideSplit("},act:{")
key = aryTemp(0)
'etc...
You may be able do this more memory efficiently, though, as this method creates a number of temporary string allocations.
Kishore's solution is perfect, but here is another solution that works with regex:
Dim input As String = "req:{REQUESTER_NAME},key:{abc},act:{UPDATE},sku:{ABC123,DEF-123},qty:{10,5}"
Dim Array = Regex.Split(input, ":{|}|,")
This does essentially the same, it uses regex to split on :{, } and ,. The solution might be a bit shorter though. The values will be put into the array like this:
"req", "REQUESTER_NAME","", ... , "qty", "10", "5", ""
Notice after the parameter and its value(s) there will be an empty string in the array. When looping over the array you can use this to let the program know when a new parameter starts. Then you can create a new array/data structure to store its values.

Parse multiple values from string c#

Suppose I have written "5 and 6" or "5+6". How can I assign 5 and 6 to two different variables in c# ?
P.S. I also want to do certain work if certain chars are found in string. Suppose I have written 5+5. Will this code do that ?
if(string.Contains("+"))
{
sum=x+y;
}
string input="5+5";
var numbers = Regex.Matches(input, #"\d+")
.Cast<Match>()
.Select(m => m.Value)
.ToList();
Personally, I would vote against doing some splitting and regular expression stuff.
Instead I would (and did in the past) use one of the many Expression Evaluation libraries, like e.g. this one over at Code Project (and the updated version over at CodePlex).
Using the parser/tool above, you could do things like:
A simple expression evaluation then could look like:
Expression e = new Expression("5 + 6");
Debug.Assert(11 == e.Evaluate());
To me this is much more error-proof than doing the parsing all by myself, including regular expressions and the like.
You should use another name for your string than string
var numbers = yourString.Split("+");
var sum = Convert.ToInt32(numbers[0]) + Convert.ToInt32(numbers[1]);
Note: Thats an implementation without any error checking or error handling...
If you want to assign numbers from string to variables, you will have to parse string and make conversion.
Simple example, if you have text with only one number
string text = "500";
int num = int.Parse(text);
Now, if you want to parse something more complicated, you can use split() and/or regex to get all numbers and operators between them. Than you just iterate array and assign numbers to variables.
string text = "500+400";
if (text.Contains("+"))
{
String[] data = text.Split("+");
int a = int.Parse(data[0]);
int b = int.Parse(data[1]);
int res = a + b;
}
Basicly, if you have just 2 numbers and operazor between them, its ok. If you want to make "calculator" you will need something more, like Binary Trees or Stack.
Use the String.Split method. It splits your string rom the given character and returns a string array containing the value that is broken down into multiple pieces depending on the character to break, in this case, its "+".
int x = 0;
int y = 0;
int z = 0;
string value = "5+6";
if (value.Contains("+"))
{
string[] returnedArray = value.Split('+');
x = Convert.ToInt32(returnedArray[0]);
y = Convert.ToInt32(returnedArray[1]);
z = x + y;
}
Something like this may helpful
string strMy = "5&6";
char[] arr = strMy.ToCharArray();
List<int> list = new List<int>();
foreach (char item in arr)
{
int value;
if (int.TryParse(item.ToString(), out value))
{
list.Add(item);
}
}
list will contains all the integer values
You can use String.Split method like;
string s = "5 and 6";
string[] a = s.Split(new string[] { "and", "+" }, StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine(a[0].Trim());
Console.WriteLine(a[1].Trim());
Here is a DEMO.
Use regex to get those value and then switch on the operand to do the calculation
string str = "51 + 6";
str = str.Replace(" ", "");
Regex regex = new Regex(#"(?<rightHand>\d+)(?<operand>\+|and)(?<leftHand>\d+)");
var match = regex.Match(str);
int rightHand = int.Parse(match.Groups["rightHand"].Value);
int leftHand = int.Parse(match.Groups["leftHand"].Value);
string op = match.Groups["operand"].Value;
switch (op)
{
case "+":
.
.
.
}
Split function maybe is comfortable in use but it is space inefficient
because it needs array of strings
Maybe Trim(), IndexOf(), Substring() can replace Split() function

C# how to split a string backwards?

What i'm trying to do is split a string backwards. Meaning right to left.
string startingString = "<span class=\"address\">Hoopeston,, IL 60942</span><br>"
What I would do normally is this.
string[] splitStarting = startingString.Split('>');
so my splitStarting[1] would = "Hoopeston,, IL 60942</span"
then I would do
string[] splitAgain = splitStarting[1].Split('<');
so splitAgain[0] would = "Hoopeston,, IL 60942"
Now this is what I want to do, I want to split by ' ' (a space) reversed for the last 2 instances of ' '.
For example my array would come back like so:
[0]="60942"
[1]="IL"
[2] = "Hoopeston,,"
To make this even harder I only ever want the first two reverse splits, so normally I would do something like this
string[] splitCity,Zip = splitAgain[0].Split(new char[] { ' ' }, 3);
but how would you do that backwards? The reason for that is, is because it could be a two name city so an extra ' ' would break the city name.
Regular expression with named groups to make things so much simpler. No need to reverse strings. Just pluck out what you want.
var pattern = #">(?<city>.*) (?<state>.*) (?<zip>.*?)<";
var expression = new Regex(pattern);
Match m = expression .Match(startingString);
if(m.success){
Console.WriteLine("Zip: " + m.Groups["zip"].Value);
Console.WriteLine("State: " + m.Groups["state"].Value);
Console.WriteLine("City: " + m.Groups["city"].Value);
}
Should give the following results:
Found 1 match:
1. >Las Vegas,, IL 60942< has 3 groups:
1. Las Vegas,, (city)
2. IL (state)
3. 60942 (zip)
String literals for use in programs:
C#
#">(?<city>.*) (?<state>.*) (?<zip>.*?)<"
One possible solution - not optimal but easy to code - is to reverse the string, then to split that string using the "normal" function, then to reverse each of the individual split parts.
Another possible solution is to use regular expressions instead.
I think you should do it like this:
var s = splitAgain[0];
var zipCodeStart = s.LastIndexOf(' ');
var zipCode = s.Substring(zipCodeStart + 1);
s = s.Substring(0, zipCodeStart);
var stateStart = s.LastIndexOf(' ');
var state = s.Substring(stateStart + 1);
var city = s.Substring(0, stateStart );
var result = new [] {zipCode, state, city};
Result will contain what you requested.
If Split could do everything there would be so many overloads that it would become confusing.
Don't use split, just custom code it with substrings and lastIndexOf.
string str = "Hoopeston,, IL 60942";
string[] parts = new string[3];
int place = str.LastIndexOf(' ');
parts[0] = str.Substring(place+1);
int place2 = str.LastIndexOf(' ',place-1);
parts[1] = str.Substring(place2 + 1, place - place2 -1);
parts[2] = str.Substring(0, place2);
You can use a regular expression to get the three parts of the string inside the tag, and use LINQ extensions to get the strings in the right order.
Example:
string startingString = "<span class=\"address\">East St Louis,, IL 60942</span><br>";
string[] city =
Regex.Match(startingString, #"^.+>(.+) (\S+) (\S+?)<.+$")
.Groups.Cast<Group>().Skip(1)
.Select(g => g.Value)
.Reverse().ToArray();
Console.WriteLine(city[0]);
Console.WriteLine(city[1]);
Console.WriteLine(city[2]);
Output:
60942
IL
East St Louis,,
How about
using System.Linq
...
splitAgain[0].Split(' ').Reverse().ToArray()
-edit-
ok missed the last part about multi word cites, you can still use linq though:
splitAgain[0].Split(' ').Reverse().Take(2).ToArray()
would get you the
[0]="60942"
[1]="IL"
The city would not be included here though, you could still do the whole thing in one statement but it would be a little messy:
var elements = splitAgain[0].Split(' ');
var result = elements
.Reverse()
.Take(2)
.Concat( new[ ] { String.Join( " " , elements.Take( elements.Length - 2 ).ToArray( ) ) } )
.ToArray();
So we're
Splitting the string,
Reversing it,
Taking the two first elements (the last two originally)
Then we make a new array with a single string element, and make that string from the original array of elements minus the last 2 elements (Zip and postal code)
As i said, a litle messy, but it will get you the array you want. if you dont need it to be an array of that format you could obviously simplfy the above code a little bit.
you could also do:
var result = new[ ]{
elements[elements.Length - 1], //last element
elements[elements.Length - 2], //second to last
String.Join( " " , elements.Take( elements.Length - 2 ).ToArray( ) ) //rebuild original string - 2 last elements
};
At first I thought you should use Array.Reverse() method, but I see now that it is the splitting on the ' ' (space) that is the issue.
Your first value could have a space in it (ie "New York"), so you dont want to split on spaces.
If you know the string is only ever going to have 3 values in it, then you could use String.LastIndexOf(" ") and then use String.SubString() to trim that off and then do the same again to find the middle value and then you will be left with the first value, with or without spaces.
Was facing similar issue with audio FileName conventions.
Followed this way: String to Array conversion, reverse and split, and reverse each part back to normal.
char[] addressInCharArray = fullAddress.ToCharArray();
Array.Reverse(addressInCharArray);
string[] parts = (new string(addressInCharArray)).Split(new char[] { ' ' }, 3);
string[] subAddress = new string[parts.Length];
int j = 0;
foreach (string part in parts)
{
addressInCharArray = part.ToCharArray();
Array.Reverse(addressInCharArray);
subAddress[j++] = new string(addressInCharArray);
}

Categories