1

Regex is not my friend. He would find a good man to help me. User can specify working time in the format: 00:00-12:30 or 00:00-12:30,14:15-18:00

I would therefore need to verify the input complies with the variants, but nothing else should pass. I tried to combine pieces like

[0-9] {2} [0-9] {2}

But I really do not understand: /

8
  • need the : between too Commented Jul 17, 2017 at 18:59
  • You are expected to try to write the code yourself. After doing more research if you have a problem post what you've tried with a clear explanation of what isn't working and provide a Minimal, Complete, and Verifiable example. Read How to Ask a good question. Be sure to take the tour and read this. Commented Jul 17, 2017 at 19:05
  • You can't have the spaces in there like that either. Your regex essentially says 2 numbers followed space with quantity 2...etc. Every character in a regex has meaning, even if it is just that literal character. Commented Jul 17, 2017 at 19:05
  • Ranges for regex are long and overly complicated. You should add your PHP usage attempt, it is unclear to me if you used [0-9] {2} [0-9] {2} or some parts of that with other code. Commented Jul 17, 2017 at 19:09
  • Regex should be used to validate a format, not content. Once you start validating that the numbers are between x and y and more, they get tons more complicated or even likely can't be done at all (for example, comparing that a is less than b). They can be done by much better tools. For example, to validate a number is between 0 and 23, you can either say if($number >= 0 && $number <= 23) or you can use a regex like: /^([01]?[\d|2[0-3])$/. Which would you think is easier to understand? Commented Jul 17, 2017 at 19:10

2 Answers 2

3

Here you go.

((?&hh_mm))-((?&hh_mm))(?:,((?&hh_mm))-((?&hh_mm)))?(?(DEFINE)(?<hh_mm>(?:[01]\d|2[0-3]):[0-5]\d))

https://regex101.com/r/lUQHun/1

Capture groups provided for hh:mm of each part.

Expanded

 ( (?&hh_mm) )                 # (1), hh:mm
 -                             # -
 ( (?&hh_mm) )                 # (2), hh:mm

 (?:                           # Optional 
      ,                             # ,
      ( (?&hh_mm) )                 # (3), hh:mm
      -                             # -
      ( (?&hh_mm) )                 # (4), hh:mm
 )?
 (?(DEFINE)
      (?<hh_mm>                    
           (?: [01] \d | 2 [0-3] )
           :
           [0-5] \d 
      )                            
 )
Sign up to request clarification or add additional context in comments.

Comments

1

You may use

'~^((?:[01]\d|2[0-3]):[0-5]\d)-(?1)(?:,(?1)-(?1))?$~'

See the regex demo

It matches

  • ^ - the start of string
  • ((?:[01]\d|2[0-3]):[0-5]\d) - a capturing group #1 that matches:
    • (?:[01]\d|2[0-3]) - either of the two alternatives:
      • [01]\d - 0 or 1 followed with any digit
      • | - or
      • 2[0-3] - 2 followed with a digit from 0 to 3
    • : - a colon
    • [0-5] - a digit from 0 to 5
    • \d - any digit
  • - - a hyphen
  • (?1) - the pattern defined inside Group 1
  • (?:,(?1)-(?1))? - an optional sequence (? at the end makes the regex engine match the patterns inside the non-capturing (?:...) match 1 or 0 times) that matches
    • , - a comma
    • (?1)-(?1) - Group 1 pattern, - and again Group 1 pattern
  • $ - end of string

Note that the (?1) is a subroutine call that is used to reuse a part of the pattern inside (...) capturing parentheses. (?1) means take the pattern defined in the first pair of unescaped parentheses in the pattern.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.