Reputation: 3803
I have written the following regex to match human-readable time at the command-line:
^(?:(?:(?:(\d+)d\s*)?(\d+)h\s*)?(\d+)m\s*)?(\d+)s$
Using non-capturing strings, this regex matches "human-readable" time equally-well in the following formats:
1d 2h 3m 4s
1h 2m 3s
1m 2s
1s
...and...
1d2h3m4s
1h2m3s
1m2s
1s
In this regex, if I include a minutes
value, I also have to include a seconds
value. I.e., I can't simply provide 15m
or 1d3m
, I have to provide 15m0s
or 1d0h3m0s
.
Is it possible to extend a regex to match these latter two use cases? How? Please note: I'm not necessarily looking for a drop-in solution, but a pointer in the right direction would be greatly appreciated.
Just a brief update that I made awhile back - this is for regex in Python.
Upvotes: 3
Views: 146
Reputation: 67968
your seconds files is not optional.there is no ? after it.so all fields not containg s will fail.
See demo.
http://regex101.com/r/iX5xR2/28
I have applied question mark.
Upvotes: 1
Reputation: 11041
You can use nested groups:
/^(?:(?:(?:(\d+)d\s*)?(\d+)h\s*)?(\d+)m\s*)?(\d+)s$/g
The value for d
, h
, m
and s
are in groups 1, 2, 3 and 4 respectively.
Upvotes: 0
Reputation: 89557
You can use this pattern:
\A(?=\S)(?:\d+d)?(?:\h*\d+h)?(?:\h*\d+m)?(?:\h*\d+s)?\z
The approach is to make all element optional. The lookahead at the begining ensures that there is at least a character that is not a space. (in other words, it ensures that there is at least one element)
Upvotes: 2
Reputation: 785156
Rather that maintaining that regular expression and trying to tweak it I would suggest greatly simplifying your regex to this:
/ *(\d+)([dhms])/gm
As you can see it matches all your current and proposed strings. You can then post-process both captured groups in your code.
Upvotes: 2