Regex extract from string xx:xx:xx format - c#

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();

Related

Convert String to List - c#

I have a list as a single string like - "['2','4','5','1']" and length of this is 17 as each char is counted.
Now I want to parse it into list object like - ['2','4','5','1'] whose length will be 4 as the number of elements in a list.
How can I do this in C#?
Can it be done without doing basic string operations? If yes then how?
Without basing string operations
Your string value looks like valid JSON array.
using Newtonsoft.Json;
var list = JsonConvert.DeserializeObject<List<char>>("['2','4','5','1']");
// => ['2','4','5','1']
If you need output as integers set output type to be list of integers and JSON serializer will convert it to integers.
var list = JsonConvert.DeserializeObject<List<int>>("['2','4','5','1']");
// => [2, 4, 5, 1]
Converting to integers will handle negative values as well ;)
var list = JsonConvert.DeserializeObject<List<int>>("['-2','4','-5','1']");
// => [-2, 4, -5, 1]
You can try regular expressions and Linq in order to Match all the integers and turn them (ToList()) into List<int>:
using System.Linq;
using System.Text.RegularExpressions;
...
string str = "['2','4','5','1']";
var result = Regex
.Matches(str, #"\-?[0-9]+") // \-? for negative numbers
.Cast<Match>()
.Select(match => int.Parse(match.Value)) // int.Parse if you want int, not string
.ToList();
Try to Split by , and then use Regex to get only digits:
var str = "['2','4','5','1']".Split(new char[] {',' })
.Select(s => Regex.Match(s, #"\d+").Value);
Or thanks to #Fildor :
var str = Regex.Matches("['2','4','5','1']", #"\d+").Cast<Match>()
.Select(s=> s.Value);

How do I fetch last 3 digits of a string in c#

How could I get the last three digits of this string?
var myString = "77441-Megrhfj654JHK";
You can try regular expressions to get last exactly 3 digits in a row:
using System.Text.RegularExpressions;
...
var myString = "77441-Megrhfj654JHK";
// Exactly 3 digits while start matching from the right
string digits = Regex.Match(myString, "[0-9]{3}", RegexOptions.RightToLeft).Value;
Console.WriteLine(digits);
Outcome:
654
Very straight forward LINQ example
public static class StringExtensions
{
public static string GetLastDigits( this string source, int count )
{
return new string( source
.Where(ch => Char.IsDigit(ch))
.Reverse()
.Take(count)
.Reverse()
.ToArray());
}
}
See working example on .net fiddle
In C# 8, you can use a range: myString[^3..];
Assuming that the input string is in a fixed format:
var lastThree = myString[^6..^3];
Or, in older C# versions:
var lastThree = myString.Substring(13, 3);
For just the last three numeric digits anywhere, something like:
var digits = new string(myString.Where(char.IsDigit).ToArray());
var lastThree = digits[^3..];
var myString = "77441-Megrhfj654JHK";
var digits = Regex.Match(myString, "[0-9]").Value;
return digits.Substring(Math.Max(digits.Length - 3,0));

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

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 {'-', ','}

How to go about splitting strings with multiple splitter values

I have a string of the following format:
0Days0hours51Minutes32Seconds
What I would like to do is split that into the 4 numerical values for
days,hours,minutes,seconds
So the values I would need back are 0, 0, 51, 32.
Are there any better ways of doing this the usual string.Split(...) method?
Ideally if there is a split by letters, so that only the numerical values remain.
string input = "0Days0hours51Minutes32Seconds";
var nums = Regex.Matches(input, #"\d+").Cast<Match>()
.Select(m => int.Parse(m.Value))
.ToList();
Instead of using String.Split(...) you could use Regex.Match(string,#"\d+") to retrieve only the numerical values.
var numbers = Regex.Split(input, #"\D+");
If you just want the numbers and don't care about the rest of the string, you can use:
string input = "0Days0hours51Minutes32Seconds";
var numbers = Regex.Matches(input, #"\d+")
.Cast<Match>()
.Select(m => int.Parse(m.Value));
However, if you want to validate the string conforms to the expected format, you could use a more comprehensive pattern.
string input = "0Days0hours51Minutes32Seconds";
var match = Regex.Match(
input,
"^(\d+)Days(\d+)hours(\d+)Minutes(\d+)Seconds$");
var days = int.Parse(match.Groups[1].Value);
var hours = int.Parse(match.Groups[2].Value);
var minutes = int.Parse(match.Groups[3].Value);
var seconds = int.Parse(match.Groups[4].Value);
I would also suggest you put these values into a useful structure like TimeSpan:
var timespan = new TimeSpan(days, hours, minutes, seconds);

Get multiple numbers from a string

I have strings like
AS_!SD 2453iur ks#d9304-52kasd
I need to get the 2 frist numbres of the string:
for that case will be:
2453 and 9304
I don't have any delimiter in the string to try a split, and the length of the numbers and string is variable, I'm working in C# framework 4.0 in a WPF.
thanks for the help, and sorry for my bad english
This solution will take two first numbers, each can have any number of digits
string s = "AS_!SD 2453iur ks#d9304-52kasd";
MatchCollection matches = Regex.Matches(s, #"\d+");
string[] result = matches.Cast<Match>()
.Take(2)
.Select(match => match.Value)
.ToArray();
Console.WriteLine( string.Join(Environment.NewLine, result) );
will print
2453
9304
you can parse them to int[] by result.Select(int.Parse).ToArray();
You can loop chars of your string parsing them, if you got a exception thats a letter if not is a number them you must to have a list to add this two numbers, and a counter to limitate this.
follow a pseudocode:
for char in string:
if counter == 2:
stop loop
if parse gets exception
continue
else
loop again in samestring stating this point
if parse gets exception
stop loop
else add char to list
Alternatively you can use the ASCII encoding:
string value = "AS_!SD 2453iur ks#d9304-52kasd";
byte zero = 48; // 0
byte nine = 57; // 9
byte[] asciiBytes = Encoding.ASCII.GetBytes(value);
byte[] asciiNumbers = asciiBytes.Where(b => b >= zero && b <= nine)
.ToArray();
char[] numbers = Encoding.ASCII.GetChars(asciiNumbers);
// OR
string numbersString = Encoding.ASCII.GetString(asciiNumbers);
//First two number from char array
int aNum = Convert.ToInt32(numbers[0]);
int bNum = Convert.ToInt32(numbers[1]);
//First two number from string
string aString = numbersString.Substring(0,2);

Categories