Home > Net >  Regex to #h #min format
Regex to #h #min format

Time:10-15

I'm trying to create a regex for "#h|H\s#min|MIN" format case insensitive For example 1H 2MIn, 2h 03min should match. 1H 60MIN, 02h 100min should not match. Thanks to Jesse point out. There is no limit on how many digits in hours. 60min suppose to be an hour. So anything above 59mins should not match. Currently, I got:

    /^[0-9]H|h\s([0-5]?\d)(MIN)|(min)$/

It's not worked for cases like 02h 100min. So which part I did do wrong? I thought ([0-5]?\d) suppose only match two digits. Thank you for any help!

Edit: I think I figured this out.

    /^\d h\s[0-5]?\dmin$/i

worked in this case. Thanks again

CodePudding user response:

The Problem

The main reason your expression isn't working as expected is because of how you're using the alternative (|) operator. This operator tells the engine that it can either match the pattern on the left side, or the pattern on the right side, but not both. The problem here is that these options aren't confined to a group, so your options aren't what you think they are.

Your entire expression is actually split into three alternative expressions. The engine is being told to match:

  • ^[0-9]H OR
  • h\s([0-5]?\d)(MIN) OR
  • (min)$

This explains the strange behavior. This can be fixed by confining what you actually want to check for to a group. In this case, since you're wanting to match H or h and MIN or min, we can create the groups (H|h) and (MIN|min). Pretty simple. After these changes your expression would look like this:

^[0-9](H|h)\s([0-5]?\d)(MIN|min)$

Regex101

However this expression has another problem. It only matches one digit in the hour section. This can be fixed by adding a queantifier to it. In this case we can use . This tells the engine to match the previous token between 1 and unlimited times. We can apply this to [0-9] to get [0-9] which will match any number between 0 and 9 between 1 and unlimited times. After this change your expression would look like this:

^[0-9] (H|h)\s([0-5]?\d)(MIN|min)$

Regex101

Now you have a working expression, but it can be simplified quite a bit. Let's talk about that next.

Improvements

First, you can replace [0-9] can be replaced with \d. These do exactly the same thing. They both match any digit between 0 and 9.

^\d (H|h)\s([0-5]?\d)(MIN|min)$

Regex101

Second, since this problem was caused by your need to match both upper and lower case, let's eliminate this problem entirely by using the case insensitivity (i) flag. The easiest way to apply this is by using (?i) at the beginning of your expression. This works across every language that supports Regex. With this flag, we no longer have to worry about matching upper and lower case letters. We can replace (H|h) with just h, and (MIN|min) with just min.

(?i)^\d h\s([0-5]?\d)min$

Regex101

This expression should do the job. You can save 3 more characters by replacing \s with (space) and by removing the parentheses around [0-5]?\d, but those are insignificant changes so I'll leave that up to you.

  • Related