To make a block optional, you can simply enclose it in ( ... )?
, which is the same as ( ... ){0,1}
allowing for zero or one occurrences.
Your revised expression will look like this:
/([0-2][0-9])((.|:)([0-5][0-9]))?/
This pattern will match strings such as 12
, 12:30
, and 12.30
. It will not match 5
, 5:30
, or 5.30
. To enable input of single digit hours, you can make the first digit optional like so:
/([0-2]?[0-9])((.|:)([0-5][0-9]))?/
If you use .match
method, you will observe 5 results:
["12:30", "12", ":30", ":", "30"]
You can reduce this to 3 by using non-capturing groups with (?: ... )
:
/([0-2]?[0-9])(?:(?:.|:)([0-5][0-9]))?/
With this approach, you get:
["12:30", "12", "30"]
Update:
If you want to match boundaries, there are several ways to achieve this:
- Starting with
^
anchors the front of the expression to the beginning of each line/string.
- Ending with
$
anchors the end of the expression to the end of the string.
- Using
\b
at the start or end mandates that the edge is against a word boundary.
Combining these together:
If you aim to match lines containing only the time, you can use:
/^([0-2]?[0-9])(?:(?:.|:)([0-5][0-9]))?$/
This will exclude cases like "hello 1.30" or "1.30 hello".
To match lines starting with a time, you could try:
/^([0-2]?[0-9])(?:(?:.|:)([0-5][0-9]))?/
However, this might match something like "1.30000".
If you specifically want dates at the start of lines, your best option is:
/^([0-2]?[0-9])(?:(?:.|:)([0-5][0-9]))?\b/
This will match "1.30 test" but not "1.300000". It may unfortunately also match "1.30.30", due to limitations in JavaScript's RegExp processor.
For times within strings, the regex would look like:
/\b([0-2]?[0-9])(?:(?:.|:)([0-5][0-9]))?\b/
It will match "test 1.30 test" but beware of matching ".10.10.10", indicating multiple occurrences.