When looping through elements in a List<string> I want to extract the first date time.
This is a sample line where in this case month is a single digit, month can also be a double digit e.g. 12 but not say 01.
string line = "\\\\SomeServer\\HTTP\\demo1\\index.cfm 4 KB CFM " +
"File 2/19/2019 3:48:21 PM " +
"2/19/2019 1:05:53 PM 2/19/2019 1:05:53 PM 5";
The expected result would be
2/19/2019 3:48:21 PM
I have looked at various regular expression code sample here, the following is one which properly handles single digit months only and does not return the time portion for the date (as I don't know what pattern to use).
var line = "\\\\SomeServer\\HTTP\\FolderName\\index.cfm 4 KB CFM " +
"File 02/19/2019 3:48:21 PM " +
"2/19/2019 1:05:53 PM 2/19/2019 1:05:53 PM 5";
var match = Regex.Match(line,
#"\d{2}\/\d{2}\/\d{4}");
var dateValue = match.Value;
if (!string.IsNullOrWhiteSpace(dateValue))
{
var dateTime = DateTime.ParseExact(dateValue,
"MM/dd/yyyy",
CultureInfo.CurrentCulture);
Console.WriteLine(
dateTime.ToString(CultureInfo.InvariantCulture));
}
In closing, I've looked at recommended question lite up when posting this question and have virtually no expertise creating regular expressions. I appreciate any recommendations and/or code samples to get me in the right direction.
You may use
\b\d{1,2}/\d{1,2}/\d{4}\s\d{1,2}:\d{2}:\d{2}\s?[AP]M\b
See the regex demo. The Regex.Match will get you the first match.
Details
\b - word boundary
\d{1,2}/\d{1,2}/\d{4} - one or two digits, /, one or two digits, /, four digits
\s - a whitespace
\d{1,2}:\d{2}:\d{2} - 1 or 2 digits, :, 2 digits, :, 2 digits
\s? - an optional whitespace
[AP]M - AM or PM
\b - word boundary.
Related
I'm looking for a Regex to validate a rating (1-10) + optional text.
Rating is a decimal, with 1 point, which can use both dot or comma separator.
Followed by an optional space + string.
Valid
7
7,5
7.5
7,5 This is my string
7.5 Hello
Invalid
7,75
11
7This is my string
7.This is my string
10.5 string
I've got this for getting the decimal values, but I'm not sure how to get the optional text behind it.
^(10|\d)([\.\,]\d{1,1})?$
Judging by your examples, the space after the initial number is not optional. Thus, the pattern you may use is
^(?:10|[1-9](?:[.,][0-9])?)(?:\s.*)?$
or - since a partial match with Regex.IsMatch is enough to validate the string - replace (?:\s.*)?$ with a negative lookahead (?!\S) that will require a whitespace or end of string after the number:
^(?:10|[1-9](?:[.,][0-9])?)(?!\S)
^^^^^^^
See the regex demo
Details:
^ - start of a string
(?:10|[1-9](?:[.,][0-9])?) - either 10 or a digit from 1 to 9 followed with an optional sequence of a , or . and any single digit and then...
(?:\s.*)?$ - an optional sequence of any whitespace followed with any chars up to the end of string - OR -
(?!\S) - a negative lookahead that fails the match if there is no non-whitespace char immediately to the right of the current position.
C# test:
var strs = new List<string> { "7","7,5","7.5","7,5 This is my string","7.5 Hello","7,75","11","7This is my string","7.This is my string","10.5 string"};
var pattern = #"^(?:10|[1-9](?:[.,][0-9])?)(?:\s.*)?$";
foreach (var s in strs)
if (Regex.IsMatch(s, pattern))
Console.WriteLine("{0} is correct.", s);
else
Console.WriteLine("{0} is invalid.", s);
Output:
7 is correct.
7,5 is correct.
7.5 is correct.
7,5 This is my string is correct.
7.5 Hello is correct.
7,75 is invalid.
11 is invalid.
7This is my string is invalid.
7.This is my string is invalid.
10.5 string is invalid.
I have below text line and I intend to extract the "date" after the ",", i,e,
1 Sep 2015
Allocation/bundle report 10835.0000 Days report step 228, 1 Sep 2015
I wrote the below regex code and it returns empty in the match.
`Regex regexdate = new Regex(#"\Allocation/bundle\s+\report\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\,\+(\S)+\s+(\S)+\s+(\S)"); // to get dates
MatchCollection matchesdate = regexdate.Matches(text);
Can you advice about what's wrong with the Regex format that I mentioned?
The \A is an anchor asserting the start of string. You must have meant A. (\S)+ must be turned into (\S+). Also, \r is a carriage return matching pattern, again remove the backslash to turn \r into r.
Use
#"Allocation/bundle\s+report\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\,\s+(\S+)\s+(\S+)\s+(\S+)"
See the regex demo
Note that the last part of the regex may be made a bit more specific to match 1+ digits, then some letters and then 4 digits: (\S+)\s+(\S+)\s+(\S+) -> (\d+)\s+(\p{L}+)\s+(\d{4})
Can you do it without Regex? Here's an example using a bit of help from LINQ.
var text = "Allocation/bundle report 10835.0000 Days report step 228, 1 Sep 2015";
var sDate = text.Split(',').Last().Trim();
if (string.IsNullOrEmpty(sDate))
{
Console.WriteLine("No date found.");
}
else
{
Console.WriteLine(sDate); // Returns "1 Sep 2015"
}
I'm pretty bad at Regex (C#) with my attempts at doing the following giving non-sense results.
Given string: 058:09:07
where only the last two digits are guaranteed, I need the result of:
"58y 9m 7d"
The needed rules are:
The last two digits "07" are days group and always present. If "00", then only the last "0" is to be printed,
The group immediately to the left of "07" which ends with ":" signify the months and are only present if enough days are present to lead into months. Again, if "00", then only the last "0" is to be printed,
The group immediately to the left of "09:" which ends with ":" signify years and will only be present if more then 12 months are needed.
In each group a leading "0" will be dropped.
(This is the result of an age calculation where 058:09:07 means 58 years, 9 months, and 7 days old. The ":" (colon) always used to separate years from months from days).
Example:
058:09:07 --> 58y 9m 7d
01:00 --> 1m 0d
08:00:00 --> 8y 0m 0d
00 --> 0d
Any help is most appreciated.
Well, you can pretty much do this without regex.
var str = "058:09:07";
var integers = str.Split(':').Select(int.Parse).ToArray();
var result = "";
switch(integers.Length)
{
case 1:
result = string.Format("{0}d", integers[0]); break;
case 2:
result = string.Format("{0}m {1}d", integers[0], integers[1]); break;
case 3:
result = string.Format("{0}y {1}m {2}d", integers[0], integers[1], integers[2]); break;
}
If you want to use regex so bad, that it starts to hurt, you can use this one instead:
var integers = Regex.Matches(str, "\d+").Cast<Match>().Select(x=> int.Parse(x.Value)).ToArray();
But, its overhead, of course. You see, regex is not parsing language, its pattern matching language, and should be used as one. For example, for finding substrings in strings. If you can find final substrings simply by cutting it by char, why not to use it?
DISCLAIMER: I am posting this answer for the educational purposes. The easiest and most correct way in case the whole string represents the time span eocron06's answer is to be used.
The point here is that you have optional parts that go in a specific order. To match them all correctly you may use the following regex:
\b(?:(?:0*(?<h>\d+):)?0*(?<m>\d+):)?0*(?<d>\d+)\b
See the regex demo
Details:
\b - initial word boundary
(?: - start of a non-capturing optional group (see the ? at the end below)
(?:0*(?<h>\d+):)? - a nested non-capturing optional group that matches zero or more zeros (to trim this part from the start from zeros), then captures 1+ digits into Group "h" and matches a :
0*(?<m>\d+): - again, matches zero or more 0s, then captures one or more digits into Group "m"
)? - end of the first optional group
0*(?<d>\d+) - same as the first two above, but captures 1+ digits (days) into Group "d"
\b - trailing word boundary
See the C# demo where the final string is built upon analyzing which group is matched:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
public class Test
{
public static void Main()
{
var pattern = #"\b(?:(?:0*(?<h>\d+):)?0*(?<m>\d+):)?0*(?<d>\d+)\b";
var strs = new List<string>() {"07", "09:07", "058:09:07" };
foreach (var s in strs)
{
var result = Regex.Replace(s, pattern, m =>
m.Groups["h"].Success && m.Groups["m"].Success ?
string.Format("{0}h {1}m {2}d", m.Groups["h"].Value, m.Groups["m"].Value, m.Groups["d"].Value) :
m.Groups["m"].Success ?
string.Format("{0}m {1}d", m.Groups["m"].Value, m.Groups["d"].Value) :
string.Format("{0}d", m.Groups["d"].Value)
);
Console.WriteLine(result);
}
}
}
I have this particular string:
Administrationsomkostninger I -2.889 - r0.l l0
I would like to replace these characters:r,l and i with 1.
I use this expression:
([(t|r|l|i|)])
That gives me this string:
Adm1n1s11a11onsomkos1n1nge1 1 -2.889 - 10.1 10
Now i want to replace the all digits that contains a digit followed + a whitespace
so in this case only - 10.1 10 gets converted to -10.110
Try this
string input = "Administrationsomkostninger I -2.889 - r0.l l0";
string pattern = #"(?'spaces'\s){2,}";
string output = Regex.Replace(input, pattern, " ");
I want to validate that a string follows this format (using regex):
valid: 123456789 //9 digits
valid: 12-1234567 // 2 digits + dash + 7 digits
Here's an example, how I would use it:
var r = new Regex("^[1-9]\d?-\d{7}$");
Console.WriteLine(r.IsMatch("1-2-3"));
I have the regex for the format with dash, but can't figure how to include the non-dash format???
Regex regex = new Regex("^\\d{2}-?\\d{7}$");
This will accept the two formats you want: 2 digits then an optional dash and 7 numbers.
^ \d{9} | \d{2} - \d{7} $
Remove the spaces, they are there for readability.