Best way to change this String-line into multiple Int's? - c#

I have some strings that looke like this:
"97-145, 3-5, 77-87, 5-10"
i need every value (97, 145, 3, 5, 77, 97, 5 and 10) stored in different int variables.
I started by trying to go through the string for each character and search for '-' or ',' but unfortunately this doesn't works for all lines, because some look like this:
"97, 3, 77-87, 5-10"
so in this case, when i search for the next '-' after i stored the first value (97), it will search until it finds the next '-' character and then stores 87.
is there a better way to solve this?

You could easily do it using a Split, assuming its always - or ,:
string str = "97-145, 3-5, 77-87, 5-10";
var ints = str.Split(new string[] { "-", "," }, StringSplitOptions.None).Select(int.Parse).ToArray();
foreach (int i in ints) Console.WriteLine(i);
Which gives:
97
145
3
5
77
87
5
10
Demo: https://dotnetfiddle.net/zE0LtW

Assuming you don't need decimals, you can easily achieve this using Regex. Specifically, match \d+ and that should find all number groups. Then simply parse each group Int32.Parse or Int32.TryParse and you're done.
Here's a sample of the regex parsing: https://regex101.com/r/YrHtY5/1
Here's a quick code sample:
var input = "97-145, 3-5, 77-87, 5-10";
var regex = new Regex("\\d+");
var regexMatches = regex.Matches(input);
var results = new List<int>();
foreach(Match match in regexMatches)
results.Add(Int32.Parse(match.Value));

I replace - by , in the string and I split:
string s = "97-145, 3-5, 77-87, 5-10";
string[] sArray = s.Replace("-", ",").Split(',');
int[] iArray = Array.ConvertAll(sArray, int.Parse);
foreach (int i in iArray) {
Console.WriteLine(i);
}
But you can also split with {'-', ','}

Related

Regex extract from string xx:xx:xx format

I am very new to programming and I have a question, I am trying to use Regex method to extract hours, minutes and seconds from a string and putting them into an array, but so far I can do it with only one number:
int initialDay D = 0;
string startDay = Console.ReadLine(); //input: "It started 5 days ago"
var resultString = Regex.Match(startDay, #"\d+").Value;
initialDay = Int32.Parse(resultString); // initialDay here equals 5.
How do manage to read from a string 06: 11: 33, and transform these hours, minutes and seconds into an array of ints? So the resulting array would be like this:
int[] array = new int[] {n1, n2, n3}; // the n1 would be 6, n2 would be 11 and n3 would be 33
Thank you for your time in advance!
If the input is in this format (dd:dd:dd), you actually don't need regex in this. You can use String.Split() method. For example:
string test = "23:22:21";
string []res = test.Split(':');
The res array will now contains "23", "22", "21" as its elements. You just then need to convert them into int.
Unless you are trying to learn regular expressions, there is no reason for you to perform this parsing yourself.
Use TimeSpan.Parse() method for this task.
You could use string.Split() to get an array of elements separated by :. Then you can loop through it, int.Parse the elements and assign them to the integer array.
string[] buffer = startDay.Split(':');
int[] array = new int[buffer.Length];
for (int i = 0; i < buffer.Length; i++)
{
array[i] = int.Parse(buffer[i]);
}
Or you can use Linq's Select() to do the parsing.
int[] array = startDay.Split(':').Select(e => int.Parse(e)).ToArray();
Use Regex.Matches(string input, string pattern) like this:
var results = Regex.Matches(startDay, #"\d+");
var array = (from Match match in results
select Convert.ToInt32(match.Value))
.ToArray();
Instead regular expression, you can use TimeSpan.Parse()
Check it https://learn.microsoft.com/pl-pl/dotnet/api/system.timespan.parse?view=netframework-4.8
RegEx way:
var pattern = #"(\d{1,2})\s?\:\s?(\d{1,2})\s?\:\s?(\d{1,2})";
var input = "06 : 11 : 33";
var arr = Regex.Matches(input, pattern)
.Cast<Match>()
.SelectMany(x => x.Groups.Cast<Group>()
.Skip(1)
.Select(y => int.Parse(y.Value)))
.ToArray();
Console.WriteLine(string.Join("\n", arr));
The output:
06
11
33
regex101
If you have date as simple string you can use split method:
string dataString = "06 : 11 : 33";
string[] arrayStr = dataString.Split(':');
Then you can make int list using System.Linq:
List<int> intList = arrayStr.Select(p => Convert.ToInt32(p)).ToList();

split string to three doubles

I used C# and I would like split text comprised 3 doubles seperated by commas and spaces.
I did:
double[] doubles = mystr.Trim().Split(new char[] { ' ', ',' })
.Select(s => Convert.ToDouble(s))
.ToArray();
when mystr = 33,44,55 for example it works fine (numbers seperated by only one comma)
Also, when mystr= 33 44 55 for example it works fine (numbers seperated by only one space)
BUT, when mystr= 33, 44, 55 it doesn't works (one space after the comma between each two numbers)
It also doesn't work when mystr = 33 44 55 (two spaces between each two numbers)
In both above examples I got an unhandled exception.
How can I solve it?
Thanks!
You can add an option to remove empty entries in the Split:
var array = Array.ConvertAll(mystr.Split(new [] { ' ', ',' },
StringSplitOptions.RemoveEmptyEntries),
Convert.ToDouble);
You could use System.Text.RegularExpressions.Regex:
var pattern = #"(\d+)((,\s*|\s+)|$)";
const int RegexTimeoutSeconds = 1;
var matches = Regex.Matches(mystr, pattern, RegexOptions.None, TimeSpan.FromSeconds(RegexTimeoutSeconds));
var doubles = new List<double>();
foreach (Match match in matches)
{
var group = match.Groups[1];
var d = Convert.ToDouble(group.Value);
doubles.Add(d);
}
Just try specifying StringSplitOptions, and use StringSplitOptions.RemoveEmptyEntries to remove empty strings..
double[] doubles = mystr.Trim().Split(new char[] { ' ', ',' },StringSplitOptions.RemoveEmptyEntries)
.Select(Convert.ToDouble)
.ToArray();

String splitting with a special structure

I have strings of the following form:
str = "[int]:[int],[int]:[int],[int]:[int],[int]:[int], ..." (for undefined number of times).
What I did was this:
string[] str_split = str.Split(',');
for( int i = 0; i < str_split.Length; i++ )
{
string[] str_split2 = str_split[i].Split(':');
}
Unfortunately this breaks when some of the numbers have extra ',' inside a number. For example, we have something like this:
695,000:14,306,000:12,136000:12,363000:6
in which the followings are the numbers, ordered from the left to the right:
695,000
14
306,000
12
136000
12
363000
6
How can I resolve this string splitting problem?
If it is the case that only the number to the left of the colon separator can contain commas, then you could simply express this as:
string s = "695,000:14,306,000:12,136000:12,363000:6";
var parts = Regex.Split(s, #":|(?<=:\d+),");
The regex pattern, which identifies the separators, reads: "any colon, or any comma that follows a colon and a sequence of digits (but not another comma)".
A simple solution is split using : as delimiter. The resultant array will have numbers of the format [int],[int]. Parse through the array and split each entry using , as the delimiter. This will give you an array of [int] numbers.
It might not be the best way to do it and it might not work all the time but here's what I'd do.
string[] leftRightDoubles = str.Split(':');
foreach(string substring in leftRightDoubles){
string[] indivNumbers = str.Split(',');
//if indivNumbers.Length == 2, you know that these two are separate numbers
//if indivNumbers.Length > 2, use heuristics to determine which parts belong to which number
if(indivNumbers.Length > 2) {
for(int i = 0, i < indivNumbers.Length, i++) {
if(indivNumbers[i] != '000') { //Or use some other heuristic
//It's a new number
} else {
//It's the rest of previous number
}
}
}
}
//It's sort of pseudocode with comments (haven't touched C# in a while so I don't want to write full C# code)

Splitting on ; then on =, having issues using String.Split, regex required

"key1"="value1 http://www.example.com?a=1";"key2"="value2 http://www.example.com?a=2";
I need to split the above line 2 times, the first time it is the comma character ; and the second time on the = sign.
It doesn't work correctly because the value part has the = sign in it also.
My code doesn't work as it was assuming the value part doesnt' have an = sign in it, and it isn't using regex simply String.Split('=').
Can someone help with the regex required, I added double quotes around both the key/value to help keep things seperate.
I didn't use a regex, but you could do something like the following:
string test =#"""key1""=""value1 http://www.example.com?a=1"";""key2""=""value2 http://www.example.com?a=2""";
string[] arr = test.Split(';');
foreach (string s in arr)
{
int index = s.IndexOf('=');
string key = s.Substring(0, index);
string value = s.Substring(index+1, s.Length - index);
}
Use the String.Split(char[], int) overload (http://msdn.microsoft.com/en-us/library/c1bs0eda.aspx). The second parameter will limit the number of substrings to return. If you know your strings will always have at least 1 equal sign (key/value pairs), then set the second parameter to 2.
string x = "key1=value1 http://www.example.com?a=1;key2=value2 http://www.example.com?a=2;";
char[] equal = new char[1] { '=' };
char[] semi = new char[1] { ';' };
string[] list = x.Split(semi, StringSplitOptions.RemoveEmptyEntries);
foreach (string s in list)
{
string[] kvp = s.Split(equal, 2);
Console.WriteLine("Key: {0}, Value: {1}", kvp[0], kvp[1]);
}
-
Result:
Key: key1, Value: value1 http://www.example.com?a=1
Key: key2, Value: value2 http://www.example.com?a=2
Well what you can do, is you can use IndexOf to get the index of the first =
int i = myStr.IndexOf('=');
and then you can use the String.Substring to get the key and value
string key = myStr.Substring(0, i)
string value = myStr.SubString(i+1);
Here is some documentation on the String Class that you might find useful
You need to match not split the text
var keys= Regex.Matches(yourString,"""(.*?)""=.*?(http.*?)"";").Cast<Match>().Select(x=>
new
{
key=x.Groups[1].Value,
value=x.Groups[2].Value
}
);
foreach(key in keys)
{
key.key;//the key value
key.value;//the value
}
Your regex should look like this.
"(.+?)"="(.+?)"
Sadly I do not know C# but this should work in every language. To get the results you have to select for every match:
group(1) as keys
group(2) as values
You could also try using the Split method with multiple tokens
here this will give you a string[] of multiple values that were split out based on your tokens
if you want to remove empty Entries you could also do the code like this
string strValue = #"""key1""=""value1 http://www.example.com?a=1"";""key2""=""value2 http://www.example.com?a=2""";
string[] strSplit = strValue.Split(new string[] { "\";\"", "\"=\"", "\"" }, StringSplitOptions.RemoveEmptyEntries);
Results
strSplit {string[4]} string[]
[0] "key1"
[1] "value1 http://www.example.com?a=1"
[2] "key2"
[3] "value2 http://www.example.com?a=2"
Use String.Split with StringSplitOptions.RemoveEmptyEntries and an array of strings with delimiters
string s = "\"key1\"=\"value1 http://www.example.com?a=1\";\"key2\"=\"value2 http://www.example.com?a=2\"";
string[] result = s.Split(new string[] { "\";\"", "\"=\"", "\"" },
StringSplitOptions.RemoveEmptyEntries);
result = {string[4]}
[0]: "key1"
[1]: "value1 http://www.example.com?a=1"
[2]: "key2"
[3]: "value2 http://www.example.com?a=2"
I use the following delimiters (including the double quotes):
";"
"="
"

Take only numbers from string and put in an array

ok i found this for removing all 'junk' that is not a number from a string
TextIN = " 0 . 1 ,2 ; 3 4 -5 6 ,7 ,8; 9 "
string justNumbers = new String(textIN.Where(Char.IsDigit).ToArray());
= "0123456789"
this removes all "junk" from my string leaving me just the numbers, but still how i can modify this ,
so i can have at least one delimiter for example a ' , ' b etween my numbers like "0,1,2,3,4,5,6,7,8,9" because i need to delimit this number so i can put them in an array of ints and work with them and there are not always just one digit numbers i may have 105 , 85692 etc..
any help please ?!
You can also convert to numeric values like this:
int[] numbers = Regex.Matches(textIN, "(-?[0-9]+)").OfType<Match>().Select(m => int.Parse(m.Value)).ToArray();
#L.B: agreed, but nthere might be negative values, too.
string test = string.Join(",", textIN.Where(Char.IsDigit));
For n digit numbers you can use regex.
string s = String.Join(",",
Regex.Matches(textIN,#"\d+").Cast<Match>().Select(m=>m.Value));
string justNumbers = new String(textIN.Where(Char.IsDigit).ToArray()); = "0123456789"
string[] words = justNumbers.Split(',');
will seperate the string into an array of numbers, delimited by commas.

Categories