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);
Related
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();
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 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));
I have a string that i need to remove the last number from the string.
For example
abc/wed/ash/123 or
abc/tues/1 or
abc/thurs/clou/nice/12
The string does not have a set amount of / in it, however I would like to separate the number after the last / from the string.
Therefore I would like to get
abc/wed/ash and 123
Everything I found needed a set amount of / in it for it to work.
If you need both halves you could try this:
var s = "abc/thurs/clou/nice/12";
var index = s.LastIndexOf('/');
var number = Int32.Parse(s.Substring(index + 1)); //12
var leftHalf = s.Substring(0, index); //abc/thurs/clou/nice
Get the last index of "/" on your input string, then use that result in Substring:
var input = "abc/wed/ash/123";
var lastIndex = input.LastIndexOf("/");
var part1 = input.Substring(0, lastIndex); // "abc/wed/ash"
var part2 = input.Substring(lastIndex + 1); // "123"
You can use regular expressions:
const string Input = "abc/def/123";
var regex = new Regex(#"(.+)/(\d+)$");
foreach (var group in regex.Match(Input).Groups)
Console.WriteLine(group.ToString());
Console.ReadKey();
UPDATE
OK, maybe I should do some explaining. By specifying a pattern, you can express quite cleanly what are the parts of your input that are of interest to you. In this case, for example, the pattern #(.+)/(\d+) tells the engine that you expect the input to contain any number of any characters, then a dash, then a number of digits. $ means that should be the end of the input.
When processing text input, consider regular expressions. :)
You can accomplish this in a variety of approaches, the cleanest approach is the answer by Francies. Which would be:
// Performant:
var input = "/Product/Electrical/Wire/4421";
var index = input.LastIndexOf('/');
var id = int.Parse(input.Substring(index + 1));
var url = input.Substring(0, index);
You could also do the following, which is a nice alternative syntax wise:
// Easy to read syntax.
var input = "/Product/Electrical/Wire/4421";
var id = input.Skip(input.LastIndexOf('/') + 1);
var url = input.Take(input.LastIndexOf('/'));
If you only need the number, you could do:
var input = "/Product/Electrical/Wire/4421";
var id = input.Split('/').Last();
Regex is your friend
Regex regex = new Regex(#"(.*?)(\d+)$");
Match match = regex.Match("abc/tues/1");
Console.WriteLine(match.Groups[1].Value); -->abc/tues/
Console.WriteLine(match.Groups[2].Value); -->1
I have a string like this :
X LIMITED COMPANY (52100000/58447000)
I want to extract X LIMITED COMPANY, 52100000 and 58447000 seperately.
I'm extracting X LIMITED COMPANY like this :
companyName = Regex.Match(mystring4, #"[a-zA-Z\s]+").Value.Trim();
But I'm stuck with extracting numbers, they can be 1, 2 or large numbers in the example. Can you show me how to extract those numbers? Thanks.
Try regular expressions with alternative | (or):
Either word symbols (but not digits) [\w-[\d]][\w\s-[\d]]+)
Digits only ([0-9]+)
E.g.
string mystring4 = #"AKASYA CAM SANAYİ VE TİCARET LİMİTED ŞİRKETİ(52100000 / 58447000)";
string[] values = Regex
.Matches(mystring4, #"([\w-[\d]][\w\s-[\d]]+)|([0-9]+)")
.OfType<Match>()
.Select(match => match.Value.Trim())
.ToArray();
Test
// X LIMITED COMPANY
// 52100000
// 58447000
Console.Write(string.Join(Environment.NewLine, values));
I suggested changing the initial pattern [a-zA-Z\s]+ into [a-zA-Z][a-zA-Z\s]+ in order to skip matches which contain separators only (e.g. " ")
Try using named groups:
var s = "X LIMITED COMPANY (52100000 / 58447000)";
var regex = new Regex(#"(?<CompanyName>[^\(]+)\((?<Num1>\d+)\s*/\s*(?<Num2>\d+)\)");
var match = regex.Match(s);
var companyName = match.Groups["CompanyName"];
If the format is fixed, you could try this:
var regex = new Regex(#"^(?<name>[^\(]+)\((?<n1>\d+)/(?<n2>\d+)\)");
var match = regex.Match(input);
var companyName = match.Groups["name"].Value;
var number1 = Convert.ToInt64(match.Groups["n1"].Value);
var number2 = Convert.ToInt64(match.Groups["n2"].Value);
This matches everything up to the open parentheses and puts it into a named group "name". Then it matches two numbers within parentheses, separated by "/" and puts them into groups named "n1" and "n2" respectively.