Abozanona
Abozanona

Reputation: 2285

How to build regex for not returning empty string if none of the groups return result

I'm trying to build a regex to match timesheet hours entry where user enters his hours in the format 20h 50m.

In this format, the user can either enter hours only 20h, or minutes only 50m or both hours and minutes 20h 50m.

Sample matches

45m
1h
2h 45m

The numbers can be anything other than 20 or 50.

I came up with this regex ((([0-9]+h)\s([0-9]+m))|([0-9]+h)|([0-9]+m)){1}, which is long and I'm trying to reduce it.

So I tried different solution: ((\d+h)?([\s]*(\d+m))?) https://regex101.com/r/ZEBsle/1/ .But the issue with this solution is that it matches empty strings and doesn't match patterns like 2h 45m.

How can I modify the last regex so it can match the following formats?

45m
1h
2h 45m

Upvotes: 3

Views: 125

Answers (3)

The fourth bird
The fourth bird

Reputation: 163217

To match all variations, you could use

\b(?:\d+h(?: \d+m)?|\d+m)\b

Explanation

  • \b A word boundary
  • (?: Non capture group
    • \d+h Match 1+ digits and h
    • (?: \d+m)? Optionally match a minute part
    • | Or
    • \d+m Match 1+ digits and m
  • ) Close group
  • \b A word boundary

Regex demo

If you want to match hours and minutes in that order, you might use anchors ^ and $

^(?:\d+h(?: \d+m)?|\d+m)$

Regex demo

Upvotes: 0

Roko C. Buljan
Roko C. Buljan

Reputation: 206028

Here's my take at it:

/(?<=\b)\d+h \d+m|\d+[hm](?=\b)/g

Example on Regex101

const str = `45m
1h
4h 35m
some text before 2h 45m and after
travelled 66miles
2m 45h this one are inversed, so treat them separately
245m`;

const times = str.match(/(?<=\b)\d+h \d+m|\d+[hm](?=\b)/g);
console.log(times);

Upvotes: 1

ZaO Lover
ZaO Lover

Reputation: 433

\d+h\s\d+m|\d+h|\d+m

I think it will work.

Upvotes: 0

Related Questions