Регулярное выражение для соответствия промежутку времени - PullRequest
1 голос
/ 05 августа 2009

Я хочу проанализировать данные, которые могут содержать смешанные шаблоны, такие как

1-4pm
1pm-5pm
noon to 11pm
noon to midnight
etc.

Я хочу извлечь время начала и окончания. Как я могу достичь этого с помощью регулярных выражений. Я знаю, что не могу поддерживать все возможные форматы ввода, но как мне добиться максимальной поддержки?


это мое выражение ^ (([AZ] +)?) \ С * ([0-9] {1,2} [:]? [0-9] {0,2} \ с * [Я | вечера . | ам | PM] [] ) \ S * [- | к | \ | / | =] \ S (([AZ] +?) | (? [0-9] {1,2} [:]? [.]? [0-9] {0,2} \ с * [я | ч | | ч вечера] )) $

, который охватывает почти все комбинации. Я просто хочу знать, есть ли оптимизация в этом регулярном выражении. Здесь dayPart будет использовать все начальные нецифровые символы для обработки, если Timespan начинается с полудня, полуночи и т. Д. Или любого значения, которое мы можем игнорировать, например, в воскресенье. startTime будет пытаться использовать любое время в любом формате, если он там есть. то же самое для endPart и EndTime.

Ответы [ 3 ]

2 голосов
/ 05 августа 2009

Сначала определите шаблон, который соответствует одному моменту времени. Учитывая ваши примеры, это может быть что-то вроде:

(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» и рассчитайте время на основе этого.

Как только вы разберетесь с ним таким образом, вам будет легче возиться с составными частями и сделать выражение более понятным. Однако то же самое можно сделать в некоторых языках, которые поддерживают многострочные выражения с комментариями.

1 голос
/ 05 августа 2009

В зависимости от языка вы можете «создать» соответствующий шаблон. Например, Ruby позволит вам сделать что-то вроде:

time_spec = /noon|midnight|\d{1,2}/
sep = /-|to/
match = /#{time_spec}\s*#{sep}\s*#{time_spec}/

Но, поскольку это кажется чем-то более сложным по мере расширения, почему бы не создать какой-то синтаксический анализатор (использующий flex / yacc?), Который будет поддерживать намного лучше, чем регулярное выражение? Когда вы начнете поддерживать диапазон ввода, такой как 1 pm/1p/13:00/13, регулярное выражение начнет создавать больше проблем, чем решений.

0 голосов
/ 05 августа 2009

Без особого продолжения похоже, что вы можете разделить на основе "-" или "to".

^(.+) ?(-|to) ?(.+)$

Это будет захватывать время начала в первой группе и время окончания в третьей. Если вам нужен более конкретный синтаксис, вам нужно будет указать, какой вариант регулярного выражения вы собираетесь использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...