Reputation: 3547
I want to make a regex that validates "human readable" time format, where it should looks like this:
1w 1d 1h 1m
and the accepted time units are (in-case sensitive):
each time unit is optional and should be existed only once at most, so the following formats should be also (for example):
and this is what I tried so far:
/((\dw) (\dd) (\dh) (\dm))/i
the above expression will validate all of the lists formats, but it will neglect the spaces between time units, I want to make the space mandatory between a time unit and another.
Upvotes: 1
Views: 447
Reputation: 48711
For validating those strings you need a more comprehensive regular expression. The following regex matches at both ends of input string and ensures repeating letters are not going to happen using a negative lookahead:
^(?!.*([wdhml]).*\1)\d*\.?\d+[wdhml](?: \d*\.?\d+[wdhml])*$
\d*\.?\d+
is used to allow decimals e.g. 1.5
or .5
(but care it doesn't allow 1.
)
See live demo here
A shorter revision but less readable one of above regex is (credits of such mixing goes to @bobblebubble):
^(?:\d*\.?\d+([wdhml])(?!.*\1)(?: (?=.)|$))+$
Upvotes: 3
Reputation: 33439
console.clear();
dates = [
// true
"4w 1m",
"4w 3d 2h 1m",
"3d",
"2h",
"1m",
"3d 2h",
// false
"4w3d",
"2h 3d",
"42",
"Lorem ipsum",
"4w 3d 2h 2h",
"1m 1m"
];
reg = /^\s*(\d{1,2}w\s+)?(\d{1,2}d\s+)?(\d{1,2}h\s+)?(\d{1,2}m\s+)?$/;
dates.forEach(function(item, index, arr) {
console.log(item, this.test(item))
}, reg)
Upvotes: 1
Reputation: 3609
Try Regex: ^(?=.*\d[wdhm])(?:\dw)?(?: ?(?<=^| )(?:\dd))?(?: ?(?<=^| )(?:\dh))?(?: (?<=^| )(?:\dm))?$
Upvotes: 0
Reputation: 3721
const regex = /^(\d+w\s?)?(\d+d\s?)?(\d{1,2}h\s?)?(\d{1,2}m)?$/
const text = "1w 8d 1h 5m"
console.log(text.match(regex)["input"])
console.log(regex.test(text))
^(\d+w\s?)?(\d+d\s?)?(\d{1,2}h\s?)?(\d{1,2}m)?$
Upvotes: 3