^(?:(?:([01]?\d|2[0-3]):)?([0-5]?\d):)?([0-5]?\d)$
Explication : (notez la qualité de l'explication !)
^ # Start of string
(?: # Try to match...
(?: # Try to match...
([01]?\d|2[0-3]): # HH:
)? # (optionally).
([0-5]?\d): # MM: (required)
)? # (entire group optional, so either HH:MM:, MM: or nothing)
([0-5]?\d) # SS (required)
$ # End of string