Сначала определите шаблон, который соответствует одному моменту времени. Учитывая ваши примеры, это может быть что-то вроде:
(noon|midnight|[0-9]+\s?(am|pm)?)
Далее определите разделитель. Может быть:
(to|\-)
Наконец, объедините два первых с одним вторым. Предполагая, что ваш язык поддерживает переменные, что-то вроде:
set timePattern {(noon|midnight|[0-9]+\s?(am|pm)?)}
set separator {(to|\-)}
set fullPattern "$timePattern(\s*$separator\s*$timePattern)?"
Как только вы пройдете через движок, вы сможете найти подходящие части выражения. Возможно, вам придется запретить захват некоторых групп, но я оставлю это как упражнение для читателя. Тогда вам, вероятно, придется разбирать отдельные части, чтобы выяснить время. Например, проанализируйте «1pm» как 1 и «pm» и рассчитайте время на основе этого.
Как только вы разберетесь с ним таким образом, вам будет легче возиться с составными частями и сделать выражение более понятным. Однако то же самое можно сделать в некоторых языках, которые поддерживают многострочные выражения с комментариями.