Reputation: 2440
I have a string which could be entered as {n}d {n}h {n}m {n}s
where {n}
is a integer denoting the number of days, hours, min, sec. How would I extract this {n}
number from the string?
The user does not have to enter all 4 - d, h, m, s. He could only enter 4d which means 4 days or 5h 2s which means 5 hours and 2 sec.
Here's what I have. Definitely there should be a better way to do this. Also, does not cover all cases.
int d; int m; int h; int sec;
string [] split = textBox3.Text.Split(new Char [] {' ', ','});
List<string> myCollection = new List<string>();
foreach (string s in split)
{
d = Convert.ToInt32(s.Substring(0,s.Length-1));
h = Convert.ToInt32(split[1].Substring(1));
m = Convert.ToInt32(split[2].Substring(1));
sec = Convert.ToInt32(split[3].Substring(1));
}
dt =new TimeSpan(h,m,s);
Upvotes: 0
Views: 386
Reputation: 112352
You can refine your approach slightly
int d = 0;
int m = 0;
int h = 0;
int s = 0;
// Because of the "params" keyword, "new char[]" can be dropped.
string [] parts = textBox3.Text.Split(' ', ',');
foreach (string part in parts)
{
char type = part[part.Length - 1];
int value = Convert.ToInt32(part.Substring(0, part.Length - 1));
switch (type) {
case 'd':
d = value;
break;
case 'h':
h = value;
break;
case 'm':
m = value;
break;
case 's':
s = value;
break;
}
}
Now you have exactly the non missing parts set. The missing parts are still 0
. You can convert the values to a TimeSpan
with
var ts = TimeSpan.FromSeconds(60 * (60 * (24 * d + h) + m) + s);
This covers all cases!
Upvotes: 0
Reputation: 55389
If the order of days, hours, minutes, and seconds is fixed, then you can use a regular expression:
string input = textBox3.Text.Trim();
Match match = Regex.Match(input,
"^" +
"((?<d>[0-9]+)d)? *" +
"((?<h>[0-9]+)h)? *" +
"((?<m>[0-9]+)m)? *" +
"((?<s>[0-9]+)s)?" +
"$",
RegexOptions.ExplicitCapture);
if (match.Success)
{
int d, h, m, s;
Int32.TryParse(match.Groups["d"].Value, out d);
Int32.TryParse(match.Groups["h"].Value, out h);
Int32.TryParse(match.Groups["m"].Value, out m);
Int32.TryParse(match.Groups["s"].Value, out s);
// ...
}
else
{
// Invalid input.
}
Upvotes: 3
Reputation: 1218
There are various options here. You could either try to use the TimeSpan.TryParse function, however this requires a different input format. Another approach would be to split the string on a whitespace and iterate over each part. While doing so you can check if the part contains d, h, s, etc. and extract the value into the desired variable. You could even use RegEx to parse the string. Here is a example based on iteration:
static void Main(string[] args)
{
Console.WriteLine("Enter the desired Timespan");
string s = Console.ReadLine();
//ToDo: Make sure that s has the desired format
//Get the TimeSpan, create a new list when the string does not contain a whitespace.
TimeSpan span = s.Contains(' ') ? extractTimeSpan(new List<string>(s.Split(' '))) : extractTimeSpan(new List<string>{s});
Console.WriteLine(span.ToString());
Console.ReadLine();
}
static private TimeSpan extractTimeSpan(List<string> parts)
{
//We will add our extracted values to this timespan
TimeSpan extracted = new TimeSpan();
foreach (string s in parts)
{
if (s.Length > 0)
{
//Extract the last character of the string
char last = s[s.Length - 1];
//extract the value
int value;
Int32.TryParse(s.Substring(0, s.Length - 1), out value);
switch (last)
{
case 'd':
extracted = extracted.Add(new TimeSpan(value,0,0,0));
break;
case 'h':
extracted = extracted.Add(new TimeSpan(value, 0, 0));
break;
case 'm':
extracted = extracted.Add(new TimeSpan(0, value, 0));
break;
case 's':
extracted = extracted.Add(new TimeSpan(0, 0, value));
break;
default:
throw new Exception("Wrong input format");
}
}
else
{
throw new Exception("Wrong input format");
}
}
return extr
Upvotes: 0
Reputation: 67193
One approach might be to use sscanf()
, which would do this quite easily. I've implemented a version of this function in C# in this article.
If you needed better handling of potential syntax errors, then you'll want to just implement your own parser. I would do that by just inspecting each character, one by one.
Upvotes: 0
Reputation: 499002
Write a custom parser - using a state machine to determine what exactly each part in the string is.
The idea is to iterate over each character in the string and change state according to what it is. So, you would have a Number
state and Day
, Month
, Hour
, Seconds
states, Space
and Start
End
states.
Upvotes: 0