Converting strings to arrays c# - c#

I have manipulated a string into the following format:
Type___Product___State___Form___Qty____someType___someProduct___someState___someForm___someQty____someOtherType___someOtherProduct...
(3 underscores between values, 4 underscores representing a line break if this was a table)
What I need to do is Create 5 string arrays (string[] type, string [] product, ...)
that pull every 5th value string into it.
So example:
string[] type = {someType, someOtherType, someOtherOtherType,...}
Any help or tips would be greatly appreciated. Thanks!

This should give you an idea on how to work with the strings.
Private Sub SplitStrings(s As String)
Dim lines() As String = Split(s, "____")
For Each line As String In lines
Dim perLineTokens() As String = line.Split("___")
Next
End Sub

The functionality you need exists in this code example, but you'll need to review it and make modifications for it to fit your exact requirements (hint: % operator would be useful). Let me know if you have questions.
const string test = "Type___Product___State___Form___Qty____someType___someProduct___someState___someForm___someQty____someOtherType___someOtherProduct___someOtherState___someOtherForm___someOtherQty";
var lines = Regex.Split(test, "____");
var strings = new string[lines.Length, 5];
var lineIteration = 0;
foreach (var line in lines)
{
var values = Regex.Split(line, "___");
var valueIteration = 0;
foreach (var value in values)
{
strings[lineIteration, valueIteration] = value;
valueIteration++;
}
lineIteration++;
}

Related

better ways to combine two array items into one string

Hello Please could you suggest better ways of writing this C# code.
Basically when NumberList has missing values between '-' I am trying to rebuild the String with default Values.
The final result should be "123-10-45-9-09"
As you can see value of "second-10" is replaced as the second item in the string.
10, 9 and 09 are filled in from the value string values.
This is the bad string which is missing some values.
string NumberList = "123--45--";
I have stored this string value in my app.config file.
string valuestring = "first-12,second-10,third-99,fourth-9,fifth-09";
protected string MissingNumberString(string Number)
{
string NumberList = "123--45--";
string valuestring = "first-12,second-10,third-99,fourth-9,fifth-09";
var companyAccountList = valuestring.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
var result = NumberList.Split('-');
int counter = 0;
var builder = new System.Text.StringBuilder();
foreach (string s in companyAccountList)
{
string t = s.Substring(s.IndexOf('-') + 1);
if (string.IsNullOrEmpty(result[counter]))
builder.Append(t).Append("-");
else
{
if (companyAccountList.Length == counter)
builder.Append(result[counter]);
else
builder.Append(result[counter]).Append("-");
}
counter++;
}
return builder.ToString();
}
One way (assuming valuestring is in order and do not miss any defaults) to achieve this would be
string MissingNumber(string Number)
{
string valuestring = "first-12,second-10,third-99,fourth-9,fifth-09";
var regex = Regex.Matches(valuestring,#"(?<=-)(\d*)(?<=,)?");
var defaults = regex.Cast<Match>().Select(x=>x.Value).ToList();
var newArray = Number.Split('-').Select((x,index)=>string.IsNullOrEmpty(x)?defaults[index]:x);
return string.Join("-",newArray);
}
The code uses Regular Expression to break the ValueString and read the default values.
Regex.Matches(valuestring,#"(?<=-)(\d*)(?<=,)?");
The regular expression uses non-capturing groups to capture a number which is prefixed as by an optional "-" character and suffixed by an optional "," character.
Once the defaults are parsed into a List (assuming that the positions are in order and do not miss any values), we loop through the input string (which has been split based on delimiter), check if it is Empty, and if so, use the value from the Defaults (based on our assumption, it should have same index).
Update
Based on the comments, it looks like you other data in the original string, and hence the concerned sub-string has to be captured first.
We could update the Missing Number method as
static string MissingNumber(string Number)
{
string valuestring = "first-12,second-10,third-99,fourth-9,fifth-09";
var regexDefaultValues = Regex.Matches(valuestring,#"(?<=-)(\d*)(?<=,)?");
var defaults = regexDefaultValues.Cast<Match>().Select(x=>x.Value).ToList();
var regexNumberToParse = new Regex(#"(\d)*-(\d)*-(\d)*-(\d)*-(\d)*");
var capturedNumberFormat = regexNumberToParse.Match(Number).Value;
var newArray = capturedNumberFormat.Split('-').Select((x,index)=>string.IsNullOrEmpty(x)?defaults[index]:x);
var ValueWithDefaults = string.Join("-",newArray);
return regexNumberToParse.Replace(Number,ValueWithDefaults);
}
Demo Code

Parsing string with 3 hyphens C#

I have string COO70-123456789-12345-1. I need to parse based on the "-" not the length of the substrings and use the parsed values. I have tried using Regular expressions but having issues.Please suggest.
Also after I have split the values I need to use each values: string A = COO70, int B = 123456789, int C = 12345, short D = 1 . How do I get it in different variables A,B,C,D.
string[] results = UniqueId.Split('-');
string A = results[0];
string B = results[1];
string C = results[2];
int k_id = Convert.ToInt32(k_id);
string D = results[3];
short seq = Convert.ToInt16(seq);
string s = "COO70-123456789-12345-1";
string[] split = s.Split('-'); //=> {"COO70", "123456789", "12345", "1"}
Use indexOf
To find everything before the first hyphen use:
string original= "COO70-123456789-12345-1";
string toFirstHyphen=original.Substring(0,original.IndexOf("-"));
Or if you want every section use split like the above example.
You can verify whether the input is formatted as you want and then split to get the parts.
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string pattern = #"(?x)^(\w+-\w+-\w+-\w+)$";
Regex reg = new Regex(pattern);
string test = "word-6798-3401-001";
if((reg.Match(test).Success))
foreach (var x in test.Split(new char[] {'-'}))
Console.WriteLine(x);
}
}
So it sounds like you first want to split it, but then store it into your values.
I would do something like this:
var myString = "COO70-123456789-12345-1";
var stringSet = myString.Split("-"); // This returns an array of values.
Now we need to verify that we receive only 4 sub strings:
if (stringSet.Count != 4)
throw Exception e; // Throw a real exception, not this
From here we need to know what order our strings should be in and assign them:
var A = stringSet[0];
var B = stringSet[1];
var C = stringSet[2];
var D = stringSet[3];
While this should answer your question as posed, I would recommend you work with stringSet differently personally.

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.

Extracting data from plain text string

I am trying to process a report from a system which gives me the following code
000=[GEN] OK {Q=1 M=1 B=002 I=3e5e65656-e5dd-45678-b785-a05656569e}
I need to extract the values between the curly brackets {} and save them in to variables. I assume I will need to do this using regex or similar? I've really no idea where to start!! I'm using c# asp.net 4.
I need the following variables
param1 = 000
param2 = GEN
param3 = OK
param4 = 1 //Q
param5 = 1 //M
param6 = 002 //B
param7 = 3e5e65656-e5dd-45678-b785-a05656569e //I
I will name the params based on what they actually mean. Can anyone please help me here? I have tried to split based on spaces, but I get the other garbage with it!
Thanks for any pointers/help!
If the format is pretty constant, you can use .NET string processing methods to pull out the values, something along the lines of
string line =
"000=[GEN] OK {Q=1 M=1 B=002 I=3e5e65656-e5dd-45678-b785-a05656569e}";
int start = line.IndexOf('{');
int end = line.IndexOf('}');
string variablePart = line.Substring(start + 1, end - start);
string[] variables = variablePart.Split(' ');
foreach (string variable in variables)
{
string[] parts = variable.Split('=');
// parts[0] holds the variable name, parts[1] holds the value
}
Wrote this off the top of my head, so there may be an off-by-one error somewhere. Also, it would be advisable to add error checking e.g. to make sure the input string has both a { and a }.
I would suggest a regular expression for this type of work.
var objRegex = new System.Text.RegularExpressions.Regex(#"^(\d+)=\[([A-Z]+)\] ([A-Z]+) \{Q=(\d+) M=(\d+) B=(\d+) I=([a-z0-9\-]+)\}$");
var objMatch = objRegex.Match("000=[GEN] OK {Q=1 M=1 B=002 I=3e5e65656-e5dd-45678-b785-a05656569e}");
if (objMatch.Success)
{
Console.WriteLine(objMatch.Groups[1].ToString());
Console.WriteLine(objMatch.Groups[2].ToString());
Console.WriteLine(objMatch.Groups[3].ToString());
Console.WriteLine(objMatch.Groups[4].ToString());
Console.WriteLine(objMatch.Groups[5].ToString());
Console.WriteLine(objMatch.Groups[6].ToString());
Console.WriteLine(objMatch.Groups[7].ToString());
}
I've just tested this out and it works well for me.
Use a regular expression.
Quick and dirty attempt:
(?<ID1>[0-9]*)=\[(?<GEN>[a-zA-Z]*)\] OK {Q=(?<Q>[0-9]*) M=(?<M>[0-9]*) B=(?<B>[0-9]*) I=(?<I>[a-zA-Z0-9\-]*)}
This will generate named groups called ID1, GEN, Q, M, B and I.
Check out the MSDN docs for details on using Regular Expressions in C#.
You can use Regex Hero for quick C# regex testing.
You can use String.Split
string[] parts = s.Split(new string[] {"=[", "] ", " {Q=", " M=", " B=", " I=", "}"},
StringSplitOptions.None);
This solution breaks up your report code into segments and stores the desired values into an array.
The regular expression matches one report code segment at a time and stores the appropriate values in the "Parsed Report Code Array".
As your example implied, the first two code segments are treated differently than the ones after that. I made the assumption that it is always the first two segments that are processed differently.
private static string[] ParseReportCode(string reportCode) {
const int FIRST_VALUE_ONLY_SEGMENT = 3;
const int GRP_SEGMENT_NAME = 1;
const int GRP_SEGMENT_VALUE = 2;
Regex reportCodeSegmentPattern = new Regex(#"\s*([^\}\{=\s]+)(?:=\[?([^\s\]\}]+)\]?)?");
Match matchReportCodeSegment = reportCodeSegmentPattern.Match(reportCode);
List<string> parsedCodeSegmentElements = new List<string>();
int segmentCount = 0;
while (matchReportCodeSegment.Success) {
if (++segmentCount < FIRST_VALUE_ONLY_SEGMENT) {
string segmentName = matchReportCodeSegment.Groups[GRP_SEGMENT_NAME].Value;
parsedCodeSegmentElements.Add(segmentName);
}
string segmentValue = matchReportCodeSegment.Groups[GRP_SEGMENT_VALUE].Value;
if (segmentValue.Length > 0) parsedCodeSegmentElements.Add(segmentValue);
matchReportCodeSegment = matchReportCodeSegment.NextMatch();
}
return parsedCodeSegmentElements.ToArray();
}

How to split a string with '#' in C#

I tried to split a string wich contains these character #
domicilioSeparado = domicilio.Split(#"#".ToCharArray());
but every time the array contains just one member. I've tried a lot of combinations but anything seems to work, I also tried to replace the string with a blank space and it kinda works - the problem is that it remains a single string.
domicilio = domicilio.Replace(#"#", #" ");
How can I resolve this?
Complete code:
String[] domicilioSeparado;
String domicilio = dbRow["DOMICILIO"].ToString();
domicilioSeparado = domicilio.Split(#"#".ToCharArray());
if (Regex.IsMatch(domicilioSeparado.Last(), #"\d"))
{
String domicilioSinNum = "";
domicilioSinNum = domicilioSeparado[0];
custTable.Rows.Add(counter, dbRow["CUENTA"], nombre,
paterno, materno, domicilioSinNum, domicilioSeparado.Last(), tipoEntidad);
}
If you just want to split a string on a delimiter, in this instance '#', then you can use this:
domicilioSeparado = domicilio.Split("#");
That should give you what you want. Your second attempt simply replaces all the characters '#' in the string with ' ', which doesn't seem to be what you want. Can we see the string you're trying to split? That might help explain why it's not working.
EDIT:
Ok, here's how I think your code should look, give this a shot and let me know how it goes.
List<string> domicilioSeparado = new List<string>();
String domicilio = dbRow["DOMICILIO"].ToString();
domicilioSeparado = domicilio.Split("#");
if (Regex.IsMatch(domicilioSeparado.Last(), #"\d"))
{
String domicilioSinNum = "";
domicilioSinNum = domicilioSeparado[0];
custTable.Rows.Add(counter, dbRow["CUENTA"], nombre,
paterno, materno, domicilioSinNum, domicilioSeparado.Last(), tipoEntidad);
}
Try this:
string[] domicilioSeparado;
domicilioSeparado = domicilio.Split('#');
Some notes:
1 - It is ('#'), instead of ("#"); 2 - Replace does not split a string, it only replace that part, keeping as a single string.
In case you want an example that includes the printing of the whole array:
string domicilio = "abc#def#ghi";
string[] domicilioSeparado;
domicilioSeparado = domicilio.Split('#');
for (int i = 0; i < domicilioSeparado.Length; i++)
{
MessageBox.Show(domicilioSeparado[i]);
}
It will open a Message Box for each element within domicilioSeparado.

Categories