-1

I'd like to write a regular expression for matching both HH:MM:SS and MM:SS.
Match

  • 99:43:22
  • 1:43:22
  • 01:43:22
  • 1:43:22
  • 43:22

so I've tried

(([0-5]?[0-9]):([0-5]?[0-9]))|(([0-9]?[0-9]):([0-5]?[0-9]):([0-5]?[0-9]))

What I wanted to add was just a single OR(|) syntax with two time regex.
But it doesn't match for HH:MM:SS enter image description here what am I missing? I've already looked into those articles:

Mark Choi
  • 420
  • 6
  • 16
  • _But it doesn't work._ isn't a problem description. What doesn't work? What does it match that it shouldn't? Or what does it not match that it should? Or what errors does it give you? – Matt Burland May 22 '18 at 17:25
  • What do you get and what do you expect? – revo May 22 '18 at 17:25
  • 1
    And all your examples are HH:MM:SS, although it's unclear if you wanted to match the first one `99:43:22` or not. – Matt Burland May 22 '18 at 17:27
  • Change the order of either sides or use `\d\d?:\d\d?(?::\d\d?)?` – revo May 22 '18 at 17:29
  • 2
    If your problem is that you aren't matching the seconds in `1:43:22`, then just switch the order of the two sub matches in your OR and it should work. – Matt Burland May 22 '18 at 17:30
  • And if the first one (that starts with `99`) is supposed to be invalid, the easier way to do this would be to just use `TimeSpan.TryParse` – Matt Burland May 22 '18 at 17:34
  • @MattBurland It works. but I still don't get it. I wonder why it works with just switching the order. – Mark Choi May 22 '18 at 17:38
  • Because it evaluates each possibility one at a time. Since it's an OR, if the first condition matches, it won't check the second. So you need the stricter condition first. – Matt Burland May 22 '18 at 17:40
  • @MattBurland ahh.. Now I got it. it's just like a `if(sub-A || sub-B)` code. and the reason of `99` in the examples is because it represents elapsed time such as timer or stopwatch. – Mark Choi May 22 '18 at 17:46
  • Why downvotes..? – Mark Choi May 22 '18 at 17:47
  • @MarkChoi: Then you should be aware that you are matching `99:43:22` but not `99:43`. – Matt Burland May 22 '18 at 17:48

2 Answers2

3

Your question is unclear. From whatever little I understand, I would suggest the following regular expression:

^([01]\d?|2[0-4]):[0-5]\d(:[0-5]\d)?$
  • It makes sure that HH is between 00-24
  • It makes sure that MM is between 00-59
  • SS is optional (so it can match both HH:MM:SS and HH:MM), and if it
    is there, it is between 00-59

There might be a more efficient method out there, but I can only think of this!

Wololo
  • 841
  • 8
  • 20
2

The expression before the alternation operator is matched before the expression after the alternation operator can even be tested.

If you anchor the start and end of these expressions, like so:

(^([0-5]?[0-9]):([0-5]?[0-9]))$|^(([0-9]?[0-9]):([0-5]?[0-9]):([0-5]?[0-9])$)

... you should get the behavior you expect.

If you are matching inside of a longer string, then you could put the longest match first:

((([0-9]?[0-9]):([0-5]?[0-9]):([0-5]?[0-9])|([0-5]?[0-9]):([0-5]?[0-9])))

or rewrite the regex a bit, as follows:

((\d{1,2}:)?[0-5]?\d:[0-5]?\d)
Zak
  • 1,042
  • 6
  • 12