Why doesn't this regex pattern parse the string "Season 02 Episode 01" properly?
For example, this is not a match:
var fileName = "Its Always Sunny in Philadelphia Season 02 Episode 01 - Charlie Gets Crippled.avi"
// Regex explanation:
// Starts with "S" and can contain more letters, can continue with space, then contains two numbers.
// Then starts with "E" again and can contain more letters, can continue with space, then contains two numbers.
var pattern = #"S\w?\s?(\d\d)\s?E\w?\s?(\d\d)";
var regex = new Regex(pattern, RegexOptions.IgnoreCase);
var match = regex.Match(fileName);
Use * instead of ?
? is for 0 or 1 time. * is for 0 or more times.
Starts with "S" and can contain more letters [...]
You mean +, not ?.
var pattern = #"S\w+\s+(\d+)\s+E\w+\s+(\d+)";
Note that this regex is pretty unspecific. Watch out for false positives. I'd recommend to make the expression more specific.
Related
I need to check if a string begins with 2 specific letters and then is followed by any 4 numbers.
the 2 letters are "BR" so BR1234 would be valid so would BR7412 for example.
what bit of code do I need to check that the string is a match with the Regex in C#?
the regex I have written is below, there is probably a more efficient way of writing this (I'm new to RegEx)
[B][R][0-9][0-9][0-9][0-9]
You can use this:
Regex regex = new Regex(#"^BR\d{4}");
^ defines the start of the string (so there should be no other characters before BR)
BR matches - well - BR
\d is a digit (0-9)
{4} says there must be exactly 4 of the previously mentioned group (\d)
You did not specify what is allowed to follow the four digits. If this should be the end of the string, add a $.
Usage in C#:
string matching = "BR1234";
string notMatching = "someOther";
Regex regex = new Regex(#"^BR\d{4}");
bool doesMatch = regex.IsMatch(matching); // true
doesMatch = regex.IsMatch(notMatching); // false;
BR\d{4}
Some text to make answer at least 30 characters long :)
I want to check if an input string follows a pattern and if it does extract information from it.
My pattern is like this Episode 000 (Season 00). The 00s are numbers that can range from 0-9. Now I want to check if this input Episode 094 (Season 02) matches this pattern and because it does it should then extract those two numbers, so I end up with two integer variables 94 & 2:
string latestFile = "Episode 094 (Season 02)";
if (!Regex.IsMatch(latestFile, #"^(Episode)\s[0-9][0-9][0-9]\s\((Season)\s[0-9][0-9]\)$"))
return
int Episode = Int32.Parse(Regex.Match(latestFile, #"\d+").Value);
int Season = Int32.Parse(Regex.Match(latestFile, #"\d+").Value);
The first part where I check if the overall string matches the pattern works, but I think it can be improved. For the second part, where I actually extract the numbers I'm stuck and what I posted above obviously doesn't works, because it grabs all digits from the string. So if anyone of you could help me figure out how to only extract the three number characters after Episode and the two characters after Season that would be great.
^Episode (\d{1,3}) \(Season (\d{1,2})\)$
Captures the 2 numbers (even with length 1 to 3/2) and gives them back as a group.
You can go even further and name your groups:
^Episode (?<episode>\d{1,3}) \(Season (?<season>\d{1,2})\)$
and then call them.
Example for using groups:
string pattern = #"abc(?<firstGroup>\d{1,3})abc";
string input = "abc234abc";
Regex rgx = new Regex(pattern);
Match match = rgx.Match(input);
string result = match.Groups["firstGroup"].Value; //=> 234
You can see what the expressions mean and test them here
In your regex ^(Episode)\s[0-9][0-9][0-9]\s\((Season)\s[0-9][0-9]\)$ you are capturing Episode and Season in a capturing group, but what you actually want to capture is the digits. You could switch your capturing groups like this:
^Episode\s([0-9][0-9][0-9])\s\(Season\s([0-9][0-9])\)$
Matching 3 digits in this way [0-9][0-9][0-9] can be written as \d{3} and [0-9][0-9] as \d{2}.
That would look like ^Episode\s(\d{3})\s\(Season\s(\d{2})\)$
To match one or more digits you could use \d+.
The \s is a matches a whitespace character. You could use \s or a whitespace.
Your regex could look like:
^Episode (\d{3}) \(Season (\d{2})\)$
string latestFile = "Episode 094 (Season 02)";
GroupCollection groups = Regex.Match(latestFile, #"^Episode (\d{3}) \(Season (\d{2})\)$").Groups;
int Episode = Int32.Parse(groups[1].Value);
int Season = Int32.Parse(groups[2].Value);
Console.WriteLine(Episode);
Console.WriteLine(Season);
That would result in:
94
2
Demo C#
I'm trying to do regex pattern which will match to this:
Name[0]/Something
or
Name/Something
Verbs Name and Something will be always known.
I did for Name[0]/Something, but I want make pattern for this verb in one regex
I've tried to sign [0] as optional but it didn't work :
var regexPattern = "Name" + #"\([\d*\]?)/" + "Something"
Do you know some generator where I will input some verbs and it will make pattern for me?
Use this:
Name(\[\d+\])?\/Something
\d+ allows one or more digits
\[\d+\] allows one or more digits inside [ and ]. So it will allow [0], [12] etc but reject []
(\[\d+\])? allows digit with brackets to be present either zero times or once
\/ indicates a slash (only one)
Name and Something are string literals
Regex 101 Demo
You were close, the regex Name(\[\d+\])?\/Something will do.
The problem is with first '\' in your pattern before '('.
Here is what you need:
var str = "Name[0]/Something or Name/Something";
Regex rg = new Regex(#"Name(\[\d+\])?/Something");
var matches = rg.Matches(str);
foreach(Match a in matches)
{
Console.WriteLine(a.Value);
}
var string = 'Name[0]/Something';
var regex = /^(Name)(\[\d*\])?\/Something$/;
console.log(regex.test(string));
string = 'Name/Something';
console.log(regex.test(string));
You've tried wrong with this pattern: \([\d*\]?)/
No need to use \ before ( (in this case)
? after ] mean: character ] zero or one time
So, if you want the pattern [...] displays zero or one time, you can try: (\[\d*\])?
Hope this helps!
i think this is what you are looking for:
Name(\[\d+\])?\/Something
Name litteral
([\d+])? a number (1 or more digits) between brackets optional 1 or 0 times
/Something Something litteral
https://regex101.com/r/G8tIHC/1
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 would like to replace from a number of 16 digits, it's 5th to 10th digit.
How can that be achieved with a regular expression (C#)?
The way to do it is to capture in the inner and outer portions separately, like this:
// Split into 2 groups of 5 digits and 1 of 6
string regex = "(\\d{5})(\\d{5})(\\d{6})";
// Insert ABCDEF in the middle of
// match 1 and match 3
string replaceRegex = "${1}ABCDE${3}";
string testString = "1234567890999999";
string result = Regex.Replace(testString, regex, replaceRegex);
// result = '12345ABCDE999999'
Why use a regular expression? If by "number of 16 digits", you mean a 16 character long string representation of a number, then you'd probably be better off just using substring.
string input = "0000567890000000";
var output = input.Substring(0, 4) + "222222" + input.Substring(10, 6);
Or did you mean you want to swap the 5th and 10th digits? Your question isn't very clear.
Use the regular expression (?<=^\d{4})\d{6}(?=\d{6}$) to achieve it without capture groups.
It looks for 6 consecutive digits (5th to 10th inclusively) that are preceded by the first 4 digits and the last 6 digits of the string.
Regex.Replace("1234567890123456", #"(?<=^\d{4})\d{6}(?=\d{6}$)", "replacement");
Got it...
by creating 3 capturing groups:
([\d]{5})([\d]{5})([\d]{6})
keep capturing group1 and 3 and replace group2 with stars (or whatever)
$1*****$3
C# code below
string resultString = null;
try {
resultString = Regex.Replace(subjectString, #"([\d]{5})([\d]{5})([\d]{6})", "$1*****$2", RegexOptions.Singleline);
} catch (ArgumentException ex) {
// Syntax error in the regular expression
}