Match exactly one occurrence with regex

Consider M, T, W, TH, F, S, SU - days of the week.

I have a regex that works well, with the exception of one scenario where there is no weekday sequence, i.e. no M , T , W , TH , F , S , SU at the expected location inside the line.

For example, q10MT valid, but q10HT is not valid.

Below is my expression:

 string expression = "q(\\d*)(M)?(T(?!H))?(W)?(TH)?(F)?(S(?!U))?(SU)?"; 

In the case of q10MT , the result of q10MT correct, but in the case of q10HT output of q10 , which is incorrect, my regular expression should not return a value or an empty string if there is no match.

What changes do I need to make to achieve this?

+5
source share
4 answers

You can achieve this with a positive outlook:

 q(\\d*)(?=(?:M|T(?!H)|W|TH|F|S(?!U)|SU))(M)?(T(?!H))?(W)?(TH)?(F)?(S(?!U))?(SU)? 

Or, as @Taemyr noted, the shorter equivalent

 q(\\d*)(?=(?:M|TH?|W|TH|F|SU?))(M)?(T(?!H))?(W)?(TH)?(F)?(S(?!U))?(SU)? 

Here is a demo

In standby mode (?=(?:M|TH?|W|F|SU?)) Make sure that there is at least one required value from the rotation list that you have after waiting.

Using C # regex:

 var rx = new Regex(@"q(\d*)(?=(?:M|TH?|W|TH|F|SU?))(M)?(T(?!H))?(W)?(TH)?(F)?(S(?!U))?(SU)?"); var result = rx.Match("q10MSUT").Value; 

Result:

enter image description here

+5
source

How about the following:

 q(\d*)(M|TH?|W|F|SU?)+ 

Watch a demo with examples of matches and matches. The key change in this regex is that it uses + to do at least one match.

Remember that this decision does not require the days to be in order, and allows you to skip the days specified in the comments, it does not matter.

Edit: OP says in the comments that for each day only one match is required, for which this decision is not taken into account.

+1
source

If the order doesn't matter, you need to do something like this:

 q(?<number>\d+)((?<monday>(?<!M\D*)M)|(?<tuesday>(?<!T(?!H)\D*)T(?!H))|(?<wednesday>(?<!W\D*)W)|(?<thursday>(?<!TH\D*)TH)|(?<friday>(?<!F\D*)F)|(?<saturday>(?<!S(?!U)\D*)S(?!U))|(?<sunday>(?<!SU\D*)SU))+ 

This is appropriate if q is followed by a certain number, and then follows one or more business days. Ordering weekdays does not matter, and a negative lookbehind ensures that no business day can occur more than once.

Each weekday is fixed in its own capture group, and this group is called so that it can be removed later. “q10MTsomething” will capture “q10MT” with 10 in the capture group “number”, M in the capture group “Monday” and T in the capture group “on Tuesdays”, other capture groups will be empty. “q10TFMother” will capture “q10TFM” with a capture, as in the previous example, plus F in the “Friday” capture group. q10TFMT will capture q10TFM using capture groups, as in the previous example. "q10HT" will not match.

demo

Note that this is a regular expression string. If you enter the code, you may need to escape \ to create the correct line.

+1
source

The question has already been given. However, I want to point out another idea, using a variable lookbehind length to maintain a sequence that should be fine with .NET

 q(\d*)[MTWFSUH]+(?<=q\d*(M)?(T)?(W)?(TH)?(F)?(S)?(SU)?) 
  • [MTWFSUH] is a list of valid characters. At least one required
  • Using lookbehind for matching while maintaining consistency

Test in test tool

+1
source

All Articles