I want to match the digits before h, m, and s into their respective capture groups. I want to match all 3 groups if possible. If one or two of the other groups are missing then match the last group(s).
As seen in the image below and in this regex101, I have currently a regex of
/(\d+)(?=h)|(\d+)(?=m)|(\d+)(?=s)/g, which matches, for my test string, 12 matches with 1 group in each match.
But I want 7 matches. Where the first match contains 3 groups, the 2:nd to 4:th match contain 2 groups each and the last 3 matches contain 1 group each.
So I want:
11h22m33s
11223311h22m
112211h33s
113322m33s
223311h
1122m
2233s
33The test strings can be contained within other strings! E.g. 08:00 + 11h. See https://regex101.com/r/RWA9Oy/1
If you need to make sure the whole string matches the pattern, you can use
^(?!$)(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$
See the regex demo.
If you need to extract these strings from the longer texts, you can use
\b(?=\w)(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?\b(?!\w)
See this regex demo.
Details:
^ - start of string(?!$) - the string can't end at the very start (=cannot be empty)\b(?=\w) - a word boundary where the char immediately on the right is a word char (=is a letter, digit or _)(?:(\d+)h)? - an optional non-capturing group matching one or more digits (capturing them into Group 1) and a h letter(?:(\d+)m)? - an optional non-capturing group matching one or more digits (capturing them into Group 2) and a m letter(?:(\d+)s)? - an optional non-capturing group matching one or more digits (capturing them into Group 3) and a s letter$ - end of string\b(?!\w) - a word boundary where the char immediately on the right is NOT a word char or at the end of string.Just in case you want allow any amount of whitespace between the components, you may add \s*:
^(?!\s*$)\s*(?:(\d+)\s*h\s*)?(?:(\d+)\s*m\s*)?(?:(\d+)\s*s)?\s*$
Or, for partial matching
\b(?=\w)(?:(\d+)\s*h\s*)?(?:(\d+)\s*m\s*)?(?:(\d+)\s*s)?\b(?!\w)
See this regex demo and another regex demo.