How to parse below string in C#? - c#

Please someone to help me to parse these sample string below? I'm having difficulty to split the data and also the data need to add carriage return at the end of every event
sample string:
L,030216,182748,00,FF,I,00,030216,182749,00,FF,I,00,030216,182750,00,FF,I,00
batch of events
expected output:
L,030216,182748,00,FF,I,00 - 1st Event
L,030216,182749,00,FF,I,00 - 2nd Event
L,030216,182750,00,FF,I,00 - 3rd Event

Seems like an easy problem. Something as easy as this should do it:
string line = "L,030216,182748,00,FF,I,00,030216,182749,00,FF,I,00,030216,182750,00,FF,I,00";
string[] array = line.Split(',');
StringBuilder sb = new StringBuilder();
for(int i=0; i<array.Length-1;i+=6)
{
sb.AppendLine(string.Format("{0},{1} - {2} event",array[0],string.Join(",",array.Skip(i+1).Take(6)), "number"));
}
output (sb.ToString()):
L,030216,182748,00,FF,I,00 - number event
L,030216,182749,00,FF,I,00 - number event
L,030216,182750,00,FF,I,00 - number event
All you have to do is work on the function that increments the ordinals (1st, 2nd, etc), but that's easy to get.

This should do the trick, given there are no more L's inside your string, and the comma place is always the sixth starting from the beginning of the batch number.
class Program
{
static void Main(string[] args)
{
String batchOfevents = "L,030216,182748,00,FF,I,00,030216,182749,00,FF,I,00,030216,182750,00,FF,I,00,030216,182751,00,FF,I,00,030216,182752,00,FF,I,00,030216,182753,00,FF,I,00";
// take out the "L," to start processing by finding the index of the correct comma to slice.
batchOfevents = batchOfevents.Substring(2);
String output = "";
int index = 0;
int counter = 0;
while (GetNthIndex(batchOfevents, ',', 6) != -1)
{
counter++;
if (counter == 1){
index = GetNthIndex(batchOfevents, ',', 6);
output += "L, " + batchOfevents.Substring(0, index) + " - 1st event\n";
batchOfevents = batchOfevents.Substring(index + 1);
} else if (counter == 2) {
index = GetNthIndex(batchOfevents, ',', 6);
output += "L, " + batchOfevents.Substring(0, index) + " - 2nd event\n";
batchOfevents = batchOfevents.Substring(index + 1);
}
else if (counter == 3)
{
index = GetNthIndex(batchOfevents, ',', 6);
output += "L, " + batchOfevents.Substring(0, index) + " - 3rd event\n";
batchOfevents = batchOfevents.Substring(index + 1);
} else {
index = GetNthIndex(batchOfevents, ',', 6);
output += "L, " + batchOfevents.Substring(0, index) + " - " + counter + "th event\n";
batchOfevents = batchOfevents.Substring(index + 1);
}
}
output += "L, " + batchOfevents + " - " + (counter+1) + "th event\n";
Console.WriteLine(output);
}
public static int GetNthIndex(string s, char t, int n)
{
int count = 0;
for (int i = 0; i < s.Length; i++)
{
if (s[i] == t)
{
count++;
if (count == n)
{
return i;
}
}
}
return -1;
}
}
Now the output will be in the format you asked for, and the original string has been decomposed.
NOTE: the getNthIndex method was taken from this old post.

If you want to split the string into multiple strings, you need a set of rules,
which are implementable. In your case i would start splitting the complete
string by the given comma , and than go though the elements in a loop.
All the strings in the loop will be appended in a StringBuilder. If your ruleset
say you need a new line, just add it via yourBuilder.Append('\r\n') or use AppendLine.
EDIT
Using this method, you can also easily add new chars like L or at the end rd Event

Look for the start index of 00,FF,I,00 in the entire string.
Extract a sub string starting at 0 and index plus 10 which is the length of the characters in 1.
Loop through it again each time with a new start index where you left of in 2.
Add a new line character each time.

Have a try the following:
string stream = "L,030216,182748,00,FF,I,00, 030216,182749,00,FF,I,00, 030216,182750,00,FF,I,00";
string[] lines = SplitLines(stream, "L", "I", ",");
Here the SplitLines function is implemented to detect variable-length events within the arbitrary-formatted stream:
string stream = "A;030216;182748 ;00;FF;AA;01; 030216;182749;AA;02";
string[] lines = SplitLines(batch, "A", "AA", ";");
Split-rules are:
- all elements of input stream are separated by separator(, for example).
- each event is bounded by the special markers(L and I for example)
- end marker is previous element of event-sequence
static string[] SplitLines(string stream, string startSeq, string endLine, string separator) {
string[] elements = stream.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries);
int pos = 0;
List<string> line = new List<string>();
List<string> lines = new List<string>();
State state = State.SeqStart;
while(pos < elements.Length) {
string current = elements[pos].Trim();
switch(state) {
case State.SeqStart:
if(current == startSeq)
state = State.LineStart;
continue;
case State.LineStart:
if(++pos < elements.Length) {
line.Add(startSeq);
state = State.Line;
}
continue;
case State.Line:
if(current == endLine)
state = State.LineEnd;
else
line.Add(current);
pos++;
continue;
case State.LineEnd:
line.Add(endLine);
line.Add(current);
lines.Add(string.Join(separator, line));
line.Clear();
state = State.LineStart;
continue;
}
}
return lines.ToArray();
}
enum State { SeqStart, LineStart, Line, LineEnd };

f you want to split the string into multiple strings, you need a set of rules, which are implementable. In your case i would start splitting the complete string by the given comma , and than go though the elements in a loop. All the strings in the loop will be appended in a StringBuilder. If your ruleset say you need a new line, just add it via yourBuilder.Append('\r\n') or use AppendLine.

Related

Remove characters before character “|”

I have a software which needs to remove all of the characters before "|".
For example input
" text needs to removed | Text needs to stay "
An example output will be
"Text needs to stay"
I have the code down below. It works for single-line text but doesn't work on multiple lines. (only removes the text on the first line rest of them stays the same)
I need to make it work with multiple lines. Any ideas?
string input = richTextBox.Text;
string output = input.Substring(input.IndexOf('|') + 1);
richTextBox1.Text = output;
You could do it easily using the Lines property and a temporary List<string> to store the result of substring
List<string> newLines = new List<string>();
foreach (string s in richTextBox1.Lines)
{
// If you want only the lines with the | remove the else block
int x = s.IndexOf('|');
if(x > -1)
newLines.Add(s.Substring(x + 1).Trim());
else
newLines.Add(s);
}
richTextBox1.Lines = newLines.ToArray();
string output = "";
var myArray = input.Split("\r\n");
foreach(var ar in myArray)
if(ar.Length > 0)
output+= ar.Substring(0, ar.IndexOf('|')) + "\r\n";
Oups! i returned the first part, but i suppose you got the point
What about using LINQ for this.
E.g.:
List<string> lines = yourString.Split("\n"); //Add \r if needed
List<string> smallerLines = lines.Select(x => x.Skip(x.IndexOf('|')+1));
If needed you can always create one new string of the output:
string finalString = String.Join(String.Empty, smallerLines);
string input = richTextBox1.Text;
int len = richTextBox1.Lines.Length;
string output = "";
for (int i = 0; i <len; i++)
{
if(i!=len-1)
{
output += richTextBox1.Lines[i].Substring(input.IndexOf('|') + 1) +
Environment.NewLine;
}
else
{
output += richTextBox1.Lines[i].Substring(input.IndexOf('|') + 1);
}
}
richTextBox1.Text = output;

convert number index of string array to double array

I am reading from a text file, pulling each line, looking for the first line with 1|, and then converting it into an array. For this I only want the 4th index so that I can sum and count the array.
Here is what is converts from the text file into an array
1|123456|01/06/2019|123456|100.00|USD|DUE UPON RECEIPT|TEST1||98790125|TEST2|TEST3|N
so [0] = 1, [2] = 123456, etc. etc. I am trying to pull 100.00 from it and put it in it's own array, so that I can easily double sum, and count the elements. It's proving difficult for me since the original array is a string though.
I've tried creating a separate string array already split, and then pulling the 4th index and creating an double array that I can count and sum. I've also tried just splitting and creating an int array in one line from the str it pulls.
string str;
using (StreamReader file = new StreamReader("c:\\testdoc.txt"))
while ((str = file.ReadLine()) != null)
{
string[] strArray = str.Split('|');
if (strArray[0] == "1")
{
double[] itotals = strArray.Select(i => Convert.ToDouble(i)).ToArray();
int count = itotals.Length;
double amt = itotals.Sum();
Console.WriteLine("Count: " + count + " Amt: " + amt);
}
else
{
}
}
I expect it to find the line starting with 1|, then tell console to write count: 1 amt: 100.00, but I actually just get errors that input strings were not in the correct format. I know that I need to pull the 4th index after I split, but I'm not sure where to do that.
Try this
string str;
int count = 0;
double amt = 0;
using (StreamReader file = new StreamReader("c:\\testdoc.txt"))
while ((str = file.ReadLine()) != null)
{
string[] strArray = str.Split('|');
if (strArray[0] == "1")
{
string itotals = strArray[4];
count = count+1;
amt = amt + Convert.ToDouble(strArray[4]);
Console.WriteLine("Count: " + count + " Amt: " + amt);
}
else
{
}
}

C#: Increment only the last number of a String

I have strings that look like this:
1.23.4.34
12.4.67
127.3.2.21.3
1.1.1.9
This is supposed to be a collection of numbers, separated by '.' symbols, similar to an ip address. I need to increment only the last digit/digits.
Expected Output:
1.23.4.35
12.4.68
127.3.2.21.4
1.1.1.10
Basically, increment whatever the number that is after the last '.' symbol.
I tried this:
char last = numberString[numberString.Length - 1];
int number = Convert.ToInt32(last);
number = number + 1;
If I go with the above code, I just need to replace the characters after the last '.' symbol with the new number. How do I get this done, good folks? :)
It seems to me that one method would be to:
split the string on . to get an array of components.
turn the final component into an integer.
increment that integer.
turn it back into a string.
recombine the components with . characters.
See, for example, the following program:
using System;
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
String original = "1.23.4.34";
String[] components = original.Split('.');
int value = Int32.Parse(components[components.Length - 1]) + 1;
components[components.Length - 1] = value.ToString();
String newstring = String.Join(".",components);
Console.WriteLine(newstring);
}
}
}
which outputs the "next highest" value of:
1.23.4.35
You can use string.LastIndexOf().
string input = "127.3.2.21.4";
int lastIndex = input.LastIndexOf('.');
string lastNumber = input.Substring(lastIndex + 1);
string increment = (int.Parse(lastNumber) + 1).ToString();
string result = string.Concat(input.Substring(0, lastIndex + 1), increment);
You need to extract more than just the last character. What if the last character is a 9 and then you add 1 to it? Then you need to correctly add one to the preceding character as well. For example, the string 5.29 should be processed to become 5.30 and not simply 5.210 or 5.20.
So I suggest you split the string into its number sections. Parse the last section into an integer. Increment it and then create the string again. I leave it as an exercise for the poster to actually write the few lines of code. Good practice!
Something like this:
var ip = "1.23.4.34";
var last = int.Parse(ip.Split(".".ToCharArray(),
StringSplitOptions.RemoveEmptyEntries).Last());
last = last + 1;
ip = string.Format("{0}.{1}",ip.Remove(ip.LastIndexOf(".")) , last);
If you are dealing with IP, there will be some extra code in case of .034, which should be 035 instead of 35. But that logic is not that complicated.
It's simple as this, use Split() and Join() String methods
String test = "1.23.4.34"; // test string
String[] splits = test.Split('.'); // split by .
splits[splits.Length - 1] = (int.Parse(splits[splits.Length - 1])+1).ToString(); // Increment last integer (Note : Assume all are integers)
String answ = String.Join(".",splits); // Use string join to make the string from string array. uses . separator
Console.WriteLine(answ); // Answer : 1.23.4.35
Using a bit of Linq
int[] int_arr = numberString.Split('.').Select(num => Convert.ToInt32(num)).ToArray();
int_arr[int_arr.Length - 1]++;
numberString = "";
for(int i = 0; i < int_arr.Length; i++) {
if( i == int_arr.Length - 1) {
numberString += int_arr[i].ToString();
}
else {
numberString += (int_arr[i].ToString() + ".");
}
}
Note: on phone so can't test.
My Solution is:
private static string calcNextCode(string value, int index)
{
if (value is null) return "1";
if (value.Length == index + 1) return value + "1";
int lastNum;
int myIndex = value.Length - ++index;
char myValue = value[myIndex];
if (int.TryParse(myValue.ToString(), NumberStyles.Integer, null, out lastNum))
{
var aStringBuilder = new StringBuilder(value);
if (lastNum == 9)
{
lastNum = 0;
aStringBuilder.Remove(myIndex, 1);
aStringBuilder.Insert(myIndex, lastNum);
return calcNextCode(aStringBuilder.ToString(), index++);
}
else
{
lastNum++;
}
aStringBuilder.Remove(myIndex, 1);
aStringBuilder.Insert(myIndex, lastNum);
return aStringBuilder.ToString();
}
return calcNextCode(value, index++);
}

Split string after certain character count

I need some help. I'm writing an error log using text file with exception details. With that I want my stack trace details to be written like the below and not in straight line to avoid the user from scrolling the scroll bar of the note pad or let's say on the 100th character the strings will be written to the next line. I don't know how to achieve that. Thanks in advance.
SAMPLE(THIS IS MY CURRENT OUTPUT ALL IN STRAIGHT LINE)
STACKTRACE:
at stacktraceabcdefghijklmnopqrstuvwxyztacktraceabcdefghijklmnopqrswxyztacktraceabcdefghijk
**MY DESIRED OUTPUT (the string will write to the next line after certain character count)
STACKTRACE:
at stacktraceabcdefghijklmno
pqrstuvwxyztacktraceabcdefgh
ijklmnopqrswxyztacktraceabcd
efghijk
MY CODE
builder.Append(String.Format("STACKTRACE:"));
builder.AppendLine();
builder.Append(logDetails.StackTrace);
Following example splits 10 characters per line, you can change as you like {N} where N can be any number.
var input = "stacktraceabcdefghijklmnopqrstuvwxyztacktraceabcdefghijklmnopqrswxyztacktraceabcdefghijk";
var regex = new Regex(#".{10}");
string result = regex.Replace(input, "$&" + Environment.NewLine);
Console.WriteLine(result);
Here is the Demo
you can use the following code:
string yourstring;
StringBuilder sb = new StringBuilder();
for(int i=0;i<yourstring.length;++i){
if(i%100==0){
sb.AppendLine();
}
sb.Append(yourstring[i]);
}
you may create a function for this
string splitat(string line, int charcount)
{
string toren = "";
if (charcount>=line.Length)
{
return line;
}
int totalchars = line.Length;
int loopcnt = totalchars / charcount;
int appended = 0;
for (int i = 0; i < loopcnt; i++)
{
toren += line.Substring(appended, charcount) + Environment.NewLine;
appended += charcount;
int left = totalchars - appended;
if (left>0)
{
if (left>charcount)
{
continue;
}
else
{
toren += line.Substring(appended, left) + Environment.NewLine;
}
}
}
return toren;
}
Best , Easiest and Generic Answer :). Just set the value of splitAt to the that number of character count after that u want it to break.
string originalString = "1111222233334444";
List<string> test = new List<string>();
int splitAt = 4; // change 4 with the size of strings you want.
for (int i = 0; i < originalString.Length; i = i + splitAt)
{
if (originalString.Length - i >= splitAt)
test.Add(originalString.Substring(i, splitAt));
else
test.Add(originalString.Substring(i,((originalString.Length - i))));
}

split text in a text file

How can I split a text file where I have various length of sentences inside and I want to read the text file when I click to button1 on my form and take, extract words from that text file that are between start and the end of ' character and which contains # symbol or # symbol inside the start and end of ' character and I want to know which line is it in and output the words into the text file.
Example, lets say I have a text like
abc'123'#def'456''#ghi'
abc'123'#def'#456''#ghi'123456'
output:
1st sentence #ghi
2nd sentence #456 #ghi
PS: #def is not in start and end of ' character so not in the output
I tied with split function but couldn't make it and turned into mass: ( How can I make this. I will be pleased if someone who knows helps.
Thanks.
here ur input string is s & the string contains # or # at first index is str
int start = s.indexOf("'");
int end = s.indexOf("'", start + 1);
string str = s.SubString(start, end);
if(str.ToCharArray()[0] == "#" || str.ToCharArray()[0] == "#")
// proceed
As far as this example is concerned here is a sample code that works
string sen1="abc'123'#def'456''#ghi'";
string sen2 = "abc'123'#def'#456''#ghi'123456'";
string[] NewSen = Regex.Split(sen1, "''");
string YourFirstOP=NewSen[1].ToString(); //gets #ghi
NewSen = Regex.Split(sen2, "''");
string[] A1 = Regex.Split(NewSen[0], "'");
string[] A2 = Regex.Split(NewSen[1], "'");
string YourSecondOP= A1[A1.Length - 1] + "" + A2[A2.Length - 3].ToString();// gets #456 #ghi
But thats just this example
Hope this helps
Try this,
string testString = #"abc'123'#def'456''#ghi'abc'123'#def'#456''#ghi'123456'";
List<string> output = new List<string>();
int startIndex = 0;
int endIndex = 0;
while (startIndex >= 0 && endIndex >= 0)
{
startIndex = testString.IndexOf("'", endIndex + 1);
endIndex = testString.IndexOf("'", startIndex + 1);
if (startIndex >= 0 && endIndex >= 0)
{
string str = testString.Substring(startIndex + 1, (endIndex - startIndex) - 1);
int indexOfSpecialChar = str.IndexOf("#");
if (indexOfSpecialChar < 0)
{
indexOfSpecialChar = str.IndexOf("#");
}
if (indexOfSpecialChar >= 0)
{
output.Add(str.Substring(indexOfSpecialChar));
}
}
}
string [] Mass = s.Split('\'');
if (Mass.Length > 1)
for (int i = 1; i < (Mass.Length - 1); i += 2)
{
if (Mass[i].Contains("#") || Mass[i].Contains("#"))
// proceed
}

Categories

Resources