I am trying to extract some data from user input that should follow this format: 1d 5h 30m
, which means the user is entering an amount of time of 1 day, 5 hours and 30 minutes.
I am trying to extract the value of each part of the input. However, each group is optional, meaning that 2h 20m
is a valid input.
I am trying to be flexible in the input (in the sense that not all parts need to be input) but at the same time I don't watch my regex to match some random imput like asdfasdf20m
. This one should be rejected (no match).
So first I am getting rid of any separator the user might have used (their input can look like 4h, 10m
and that's ok):
input = input.replace(/[\s.,;_|#-]+/g, '');
Then I am capturing each part, which I indicate as optional using ?
:
var match = /^((\d+)d)?((\d+)h)?((\d+)m)?$/.exec(input);
It is kind of messy capturing an entire group including the letter when I only want the actual value, but I cannot say that cluster is optional without wrapping it with parentheses right?
Then, when an empty group is captured its value in match
is undefined
. Is there any function to default undefined
values to a particular value? For example, 0
would be handy here.
An example where input
is "4d, 20h, 55m"
, and the match
result is:
["4d20h55m", "4d", "4", "20h", "20", "55m", "55", index: 0, input: "4d20h55m"]
My main issues are:
How can I indicate a group as optional but avoid capturing it?
How can I deal with input that can potentially match, like
abcdefg6d8m
?How can I deal with an altered order? For example, the user could input
20m 10h
.
When I'm asking "how to deal with x" I mean I'd like to be able to reject those matches.