1

I need a regex in a form in order to make sure the input either:

  • starts with + or - and then has numbers (for instance: +120 or -15)
  • or is an exact hour, for instance: 17:20 or 15:23

The regex I came up with is:

^[+-][\d]*|[\d]{2}:[\d]{2}$

But it doesn't seem to work properly: each expression works separately (^[+-][\d]*$ or ^[\d]{2}:[\d]{2}$) but together with the | operator, it allows the input +120sds where it didn't when the expression was tested separately.

underscore_d
  • 6,309
  • 3
  • 38
  • 64
Dan
  • 57
  • 10
  • Group it. `^(?:[+-]\d+|\d{2}:\d{2})$` – Wiktor Stribiżew Nov 17 '17 at 13:44
  • Side note: when posting questions, there's no need to add a signature, advance thanks, explicit pleas for help, regards, salutations, etc. These things have been removed from several of your questions - if you can refrain from adding this material, it will leave volunteers with more time to edit questions from new users. Thanks! – halfer Nov 17 '17 at 13:48
  • OK sorry, I won't add these anymore. – Dan Nov 17 '17 at 14:11

1 Answers1

1

You need to group the alternatives, e.g. using a non-capturing alternation group (?:...|...). That way, both the anchors will apply to all the alternatives. Also, to match time in 24h format, you may use a more precise expression, (?:[01][0-9]|2[0-3]):[0-5][0-9] (also, see this SO thread).

^(?:[+-]\d+|(?:[01][0-9]|2[0-3]):[0-5][0-9])$
  ^^       ^                               ^

See the regex demo. Note that it seems there must be at least 1 digit after + and -, thus, use \d+ instead of \d*.

Pattern details

  • ^ - start of string -(?: - start of the grouping construct
    • [+-] - a + or -
    • \d+ - 1 or more digits
  • | - or
    • (?:[01][0-9]|2[0-3]) - 00 to 23
    • : - a colon
    • [0-5][0-9] - 00 to 59
  • ) - end of the alternation group
  • $ - end of string.
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • your regexp fails when the hour is like `1:14` instead of `01:14`. To fix it you should use: `^(?:[+-]\d+|(?:[01]{0,1}[0-9]|2[0-3]):[0-5][0-9])$` – marco Nov 17 '17 at 13:56
  • @marco I just follow OP requirement, the format is `HH:mm`, see the original regex - `[\d]{2}:[\d]{2}`. If it should work with another format, let OP change the requirements. Actually, [**it will suffice to put `?` after `[01]`**](https://regex101.com/r/DWqBpI/2) and use `^(?:[+-]\d+|(?:[01]?[0-9]|2[0-3]):[0-5][0-9])$` if the hour part can consist of just 1 digit. – Wiktor Stribiżew Nov 17 '17 at 13:57
  • oh, yes, I see. – marco Nov 17 '17 at 14:00
  • Thank you very much @WiktorStribiżew ! And yes, it has to fail when input is like `1:14` – Dan Nov 17 '17 at 14:13