String manipulation of Serial Port data - c#

I am working on creating a windows form application and I have come across a problem. I am reading data in from the serial port.
string RxString = serialPort1.ReadExisting();
This works fine but what I now want to do is extract values from my RxString and put them into their own string arrays.
This the RxString format:
GPS:050.1347,N,00007.3612,WMAG:+231\r\n
it repeats itself as more data is added from the serial port the numbers change but stay the same length, and the + changes to -. I want to put the numbers between GPS: and ,N into one string array, the numbers between N, and ,W in another string array and finally the numbers between + and \r\n in a 3rd string array.
How would I go about doing this?

Ok, Regex solution:
string pattern = #"^GPS:(?<gps>.{8}),N,(?<n>.{10}),WMAG:(\+|\-)(?<wmag>.{3})\\r\\n$";
string gps = string.Empty;
string n = string.Empty;
string wmag = string.Empty;
string input = #"GPS:050.1347,N,00007.3612,WMAG:+231\r\n";
Regex regex = new Regex(pattern);
if (regex.IsMatch(input))
{
Match match = regex.Match(input);
foreach (Capture capture in match.Groups["gps"].Captures)
gps = capture.Value;
foreach (Capture capture in match.Groups["n"].Captures)
n = capture.Value;
foreach (Capture capture in match.Groups["wmag"].Captures)
wmag = capture.Value;
}
Console.Write("GPS: ");
Console.WriteLine(gps);
Console.Write("N: ");
Console.WriteLine(n);
Console.Write("WMAG: ");
Console.WriteLine(wmag);
Console.ReadLine();

Try this:
string RxString = serialPort1.ReadExisting();
string latitude = RxString.Split(',')[0].Substring(4);
string longitude = RxString.Split(',')[2];
string mag = RxString.Split(',')[3].Substring(6).Trim();

If the string is always the same length, the best way is to use substring() method.

I'm sure there's some RegEx that could make this prettier, but I'm not great at regex so I'd checkout C#'s String.Split function. Substring would work if you know the numbers will be the same length, but if that's not a guarantee, Split would be your best bet.
You could split each line on the comma, creating an array, then use Replace to remove the extra text (like GPS: and WMAG:), if you know that's going to be the same every time.

This is not the best solution since it uses "magic" numbers and substrings - but may work for your situation since you said the string length is always the same.
var serialPortInfo = "GPS:050.1347,N,00007.3612,WMAG:+231\r\n";
private List<string> value1 = new List<string>();
private List<string> value2 = new List<string>();
private List<string> value3 = new List<string>();
private void populateValues(string s)
{
// this should give an array of the following:
// values[0] = "050.1347"
// values[1] = "N"
// values[2] = "00007.3612"
// values[3] = "WMAG:+231"
//
var values = (s.Substring(4, (s.Length - 8))).Split(',');
// populate lists
//
value1.Add(values[0]);
value2.Add(values[2]);
value3.Add(values[3].Substring(6, 3));
}
//usage
populateValues(serialPortInfo);

Related

Parse a string in c# after reading first and last alphabet

I want to cut a string in c# after reading first and last alphabet.
string name = "20150910000549659ABCD000007348summary.pdf";
string result = "ABCD000007348"; // Something like this
string name = "1234 ABCD000007348 summary.pdf";
After reading 1234 "A" comes and at last "s" comes so I want "ABCD000007348"
Simply use Regex:
string CutString(string input)
{
Match result = Regex.Match(input, #"[a-zA-Z]+[0-9]+");
return result.Value;
}
Since you didn't say if it's always a timestamp at the beginning, I've instead opted to iterate over the string to find the first alphabetical character, rather than hardcoding s.Remove(0, n); where n is however many digits are in a timestamp.
string s = "20150910000549659ABCD000007348summary.pdf";
s = s.Replace("summary.pdf", String.Empty);
int firstLetter = 0;
foreach (char c in s)
{
if (Char.IsLetter(c))
{
firstLetter = s.IndexOf(c);
break;
}
}
s = s.Remove(0, firstLetter);

Get first word on every new line in a long string?

I am trying to add a leaderboard in my unity app
I have a long string as below(just an example, actual string is http pipe data from my web service, not manually stored):
string str ="name1|10|junk data.....\n
name2|9|junk data.....\n
name3|8|junk data.....\n
name4|7|junk data....."
I want to get the first word (string before the first pipe '|' like name1,name2...) from every line and store it in an array and then get the numbers (10,9,8... arter the '|') and store it in an other one.
Anyone know whats the best way to do this?
Fiddle here: https://dotnetfiddle.net/utp4HK
code below, you may want to revisit the algorithm for performance, but if that is not an issue, this will do the trick;
using System;
public class Program
{
public static void Main()
{
string str ="name1|10|junk data.....\nname2|9|junk data.....\nname3|8|junkdata.....\nname4|7|junk data.....";
foreach (var line in str.Split('\n'))
{
Console.WriteLine(line.Split('|')[0]);
}
}
}
First split by new-line characters:
string[] lines = str.Split(new string[]{Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
Then you can use LINQ to get both arrays:
var data = lines.Select(l => l.Trim().Split('|')).Where(arr => arr.Length > 1);
string[] names = data.Select(arr => arr[0].Trim()).ToArray();
string[] numbers = data.Select(arr => arr[1].Trim()).ToArray();
Check out this link on splitting strings: http://msdn.microsoft.com/en-us/library/ms228388.aspx
You could first create an array of strings (one for each line) by splitting the long string with \n as the delimeter.
Then, you could split each line with | as the delimeter. The name would be the 0th index of the array and the number would be the 1st index of the array.
First of all, you can't have a multi line string without using verbatim string literal. With using verbatim string literal, you can split your string based on \r\n or Environment.NewLine like;
string str = #"name1|10|junk data.....
name2|9|junk data.....
name3|8|junk data.....
name4|7|junk data.....";
var array = str.Split(new []{Environment.NewLine},
StringSplitOptions.RemoveEmptyEntries);
foreach (var item in array)
{
Console.WriteLine(item.Split(new[]{"|"},
StringSplitOptions.RemoveEmptyEntries)[0].Trim());
}
Output will be;
name1
name2
name3
name4
Try this:
string str ="name1|10|junk data.....\n" +
"name2|9|junk data.....\n" +
"name3|8|junk data.....\n" +
"name4|7|junk data.....";
string[] tempArray1 = str.Split('\n');
string[] tempArray2 = null;
string[,] newArray = null;
for (int i = 0; i < tempArray1.Length; i++)
{
tempArray2 = tempArray1[i].Split('|');
if (newArray[0, 0].ToString().Length == 0)
{
newArray = new string[tempArray1.Length, tempArray2.Length];
}
for (int j = 0; j < tempArray2.Length; j++)
{
newArray[i,j] = tempArray2[j];
}
}

Extracting parts of a string c#

In C# what would be the best way of splitting this sort of string?
%%x%%a,b,c,d
So that I end up with the value between the %% AND another variable containing everything right of the second %%
i.e. var x = "x"; var y = "a,b,c,d"
Where a,b,c.. could be an infinite comma seperated list. I need to extract the list and the value between the two double-percentage signs.
(To combat the infinite part, I thought perhaps seperating the string out to: %%x%% and a,b,c,d. At this point I can just use something like this to get X.
var tag = "%%";
var startTag = tag;
int startIndex = s.IndexOf(startTag) + startTag.Length;
int endIndex = s.IndexOf(tag, startIndex);
return s.Substring(startIndex, endIndex - startIndex);
Would the best approach be to use regex or use lots of indexOf and substring to do the extracting based on te static %% characters?
Given that what you want is "x,a,b,c,d" the Split() function is actually pretty powerful and regex would be overkill for this.
Here's an example:
string test = "%%x%%a,b,c,d";
string[] result = test.Split(new char[] { '%', ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string s in result) {
Console.WriteLine(s);
}
Basicly we ask it to split by both '%' and ',' and ignore empty results (eg. the result between "%%"). Here's the result:
x
a
b
c
d
To Extract X:
If %% is always at the start then;
string s = "%%x%%a,b,c,d,h";
s = s.Substring(2,s.LastIndexOf("%%")-2);
//Console.WriteLine(s);
Else;
string s = "v,u,m,n,%%x%%a,b,c,d,h";
s = s.Substring(s.IndexOf("%%")+2,s.LastIndexOf("%%")-s.IndexOf("%%")-2);
//Console.WriteLine(s);
If you need to get them all at once then use this;
string s = "m,n,%%x%%a,b,c,d";
var myList = s.ToArray()
.Where(c=> (c != '%' && c!=','))
.Select(c=>c).ToList();
This'll let you do it all in one go:
string pattern = "^%%(.+?)%%(?:(.+?)(?:,|$))*$";
string input = "%%x%%a,b,c,d";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
// "x"
string first = match.Groups[1].Value;
// { "a", "b", "c", "d" }
string[] repeated = match.Groups[2].Captures.Cast<Capture>()
.Select(c => c.Value).ToArray();
}
You can use the char.IsLetter to get all the list of letter
string test = "%%x%%a,b,c,d";
var l = test.Where(c => char.IsLetter(c)).ToArray();
var output = string.Join(", ", l.OrderBy(c => c));
Since you want the value between the %% and everything after in separate variables and you don't need to parse the CSV, I think a RegEx solution would be your best choice.
var inputString = #"%%x%%a,b,c,d";
var regExPattern = #"^%%(?<x>.+)%%(?<csv>.+)$";
var match = Regex.Match(inputString, regExPattern);
foreach (var item in match.Groups)
{
Console.WriteLine(item);
}
The pattern has 2 named groups called x and csv, so rather than just looping, you can easily reference them by name and assign them to values:
var x = match.Groups["x"];
var y = match.Groups["csv"];

how do i delete one part of a string?

String mystring="start i dont know hot text can it to have here important=value5; x=1; important=value2; z=3;";
suggest i want to get the value of "importante" now i know how to do it with a substring, but it has 2 subistring, then how do i get, first one, and after the next? ...??
if it is not posible i want to try it... save the first. and delete since "start" until value5 for next query save the value2...
how to do any of two things?
i get the first value so...
string word = "important=";
int c= mystring.IndexOf(word);
int c2 = word.Length;
for (int i = c+c2; i < mystring.Length; i++)
{
if (mystring[i].ToString() == ";")
{
break;
}
else
{
label1.Text += mystring[i].ToString(); // c#
// label1.setText(label1.getText()+mystring[i].ToString(); //java
}
}
If you want to extract all values you could use a regex:
string input = "start i dont know hot text can it to have here important=value5; x=1; important=value2; z=3;";
Regex regex = new Regex(#"important=(?<value>\w+)");
List<string> values = new List<string>();
MatchCollection matches = regex.Matches(input);
foreach (Match match in matches)
{
string value= match.Groups["value"].Value;
values.Add(value);
}
You can save the values in an array, instead of showing them with MessageBox.
string mystring = "start i dont know hot text can it to have here important=value5; x=1; important=value2; z=3;";
string temp = mystring;
string word = "important=";
while (temp.IndexOf(word) > 0)
{
MessageBox.Show( temp.Substring(temp.IndexOf(word) + word.Length).Split(';')[0]);
temp = temp.Remove(temp.IndexOf(word), word.Length);
}
You can use 2 methods:
String.Remove()
and
String.Replace()
use regular expression, find all the match and reconstruct the string yourself.

formatting string in MVC /C#

I have a string 731478718861993983 and I want to get this 73-1478-7188-6199-3983 using C#. How can I format it like this ?
Thanks.
By using regex:
public static string FormatTest1(string num)
{
string formatPattern = #"(\d{2})(\d{4})(\d{4})(\d{4})(\d{4})";
return Regex.Replace(num, formatPattern, "$1-$2-$3-$4-$5");
}
// test
string test = FormatTest1("731478718861993983");
// test result: 73-1478-7188-6199-3983
If you're dealing with a long number, you can use a NumberFormatInfo to format it:
First, define your NumberFormatInfo (you may want additional parameters, these are the basic 3):
NumberFormatInfo format = new NumberFormatInfo();
format.NumberGroupSeparator = "-";
format.NumberGroupSizes = new[] { 4 };
format.NumberDecimalDigits = 0;
Next, you can use it on your numbers:
long number = 731478718861993983;
string formatted = number.ToString("n", format);
Console.WriteLine(formatted);
After all, .Net has very good globalization support - you're better served using it!
string s = "731478718861993983"
var newString = (string.Format("{0:##-####-####-####-####}", Convert.ToInt64(s));
LINQ-only one-liner:
var str = "731478718861993983";
var result =
new string(
str.ToCharArray().
Reverse(). // So that it will go over string right-to-left
Select((c, i) => new { #char = c, group = i / 4}). // Keep group number
Reverse(). // Restore original order
GroupBy(t => t.group). // Now do the actual grouping
Aggregate("", (s, grouping) => "-" + new string(
grouping.
Select(gr => gr.#char).
ToArray())).
ToArray()).
Trim('-');
This can handle strings of arbitrary lenghs.
Simple (and naive) extension method :
class Program
{
static void Main(string[] args)
{
Console.WriteLine("731478718861993983".InsertChar("-", 4));
}
}
static class Ext
{
public static string InsertChar(this string str, string c, int i)
{
for (int j = str.Length - i; j >= 0; j -= i)
{
str = str.Insert(j, c);
}
return str;
}
}
If you're dealing strictly with a string, you can make a simple Regex.Replace, to capture each group of 4 digits:
string str = "731478718861993983";
str = Regex.Replace(str, "(?!^).{4}", "-$0" ,RegexOptions.RightToLeft);
Console.WriteLine(str);
Note the use of RegexOptions.RightToLeft, to start capturing from the right (so "12345" will be replaced to 1-2345, and not -12345), and the use of (?!^) to avoid adding a dash in the beginning.
You may want to capture only digits - a possible pattern then may be #"\B\d{4}".
string myString = 731478718861993983;
myString.Insert(2,"-");
myString.Insert(7,"-");
myString.Insert(13,"-");
myString.Insert(18,"-");
My first thought is:
String s = "731478718861993983";
s = s.Insert(3,"-");
s = s.Insert(8,"-");
s = s.Insert(13,"-");
s = s.Insert(18,"-");
(don't remember if index is zero-based, in which case you should use my values -1)
but there is probably some easier way to do this...
If the position of "-" is always the same then you can try
string s = "731478718861993983";
s = s.Insert(2, "-");
s = s.Insert(7, "-");
s = s.Insert(12, "-");
s = s.Insert(17, "-");
Here's how I'd do it; it'll only work if you're storing the numbers as something which isn't a string as they're not able to be used with format strings.
string numbers = "731478718861993983";
string formattedNumbers = String.Format("{0:##-####-####-####-####}", long.Parse(numbers));
Edit: amended code, since you said they were held as a string in your your original question

Categories