I will explain by writing the regex in extended mode, which permits comments:
r = /
    ^     # match the beginning of the string
    (     # begin capture group 1
    1     # match 1
    [0-2] # match one of the characters 0,1,2
    |     # or
    0?    # optionally match a zero
    [1-9] # match one of the characters between 1 and 9
    )     # end capture group 1
    :     # match a colon
    (     # begin capture group 2
    [0-5] # match one of the characters between 0 and 5
    [0-9] # match one of the characters between 0 and 9
    )     # end capture group 2
    (     # begin capture group 3
    \s    # match one whitespace character
    [A|P] # match one of the characters A, | or P
    M     # match M
    )     # end capture group 3
    \)?   # optionally match a right parenthesis
    $     # match the end of the string
    /x    # extended mode
As noticed by @Mischa, [A|P] is incorrect. It should be [AP]. That's because "|" is just an ordinary character when it's within a character class.
Also, I think the regex would be improved by moving \s out of capture group 3. We therefore might write:
r = /^(1[0-2]|0?[1-9]):([0-5][0-9])\s([AP]M)\)?$/
It could be used thusly:
result = "11:39 PM" =~ r
if result
  puts "It's #{$2} minutes past #{$1}, #{ $3=='AM' ? 'anti' : 'post' } meridiem."
else
  # raise exception?
end
  #=> It's 39 minutes past 11, post meridiem.
In words, the revised regex reads as follows:
- match the beginning of the string.
- match "10","11","12", or one of the digits"1"to"9", optionally preceded by a zero, and save the match to capture group 1.
- match a colon.
- match a digit between "0"and"5", then a digit between"0"and"9", and save the two digits to capture group 2.
- match a whitespace character.
- match "A", or"P", followed by"M", and save the two characters to capture group 3.
- optionally match a right parenthesis.
- match the end of the string.