Нужна помощь с Regex для анализа времени, набранного человеком - PullRequest
1 голос
/ 19 июля 2010

Я действительно новичок в Regex и усердно работаю, но, на мой взгляд, это выходит за рамки простого.Я понимаю, как создать объект Regex в .Net, но я не уверен, как использовать его для своих конкретных целей, когда у меня есть шаблон.

Regex regex = new Regex("(at ){0,1}[0-9]{1,2}(:[0-9]{2}){0,1}(?:[ap]m?){0,1}");

Мне нужно иметь возможность взять предложение вроде«Ужин будет в 9 вечера в вашем любимом ресторане» и получите значения {«Ужин будет в вашем любимом ресторане», «9 вечера»} (удаляя «в», если он существует).

Полные (?) Контрольные примеры:

"Dinner at 9pm"            { "Dinner", "9pm" }
"Dinner at9pm"             { "Dinner", "9pm" }
"Dinner 9pm"               { "Dinner", "9pm" }
"Dinner 9p"                { "Dinner", "9pm" }
"Dinner 9a"                { "Dinner", "9am" }
"Dinner 9pZ"               { "Dinner 9pZ", "" }
"Dinner 9aZ"               { "Dinner 9aZ", "" }
"Dinner at 9"              { "Dinner", "9" }
"Dinner at 9:15pm"         { "Dinner", "9:15pm" }
"Dinner at 9:15"           { "Dinner", "9:15" }
"Dinner at9:15"            { "Dinner", "9:15" }
"Dinner at 9pm in Seattle" { "Dinner in Seattle", "9pm" }
"Dinner at9pmin Seattle"   { "Dinner in Seattle", "9pm" }
"Dinner at9in Seattle"     { "Dinner in Seattle", "9" }
"Dinner 9in Seattle"       { "Dinner 9in Seattle", "" }
"9pm Dinner"               { "Dinner", "9pm" }
"The 9pm Dinner was good"  { "The Dinner as good", "9pm" }
"Dinner at 9pmpm"          { "Dinner pm" "9pm" }
"Dinner at 9:15pmpm"       { "Dinner pm" "9:15pm" }

(просто для дальнейшего уточнения, перед числом без «:» или «am / pm» должен стоять «at», если толькоэто первое число в списке. «am» и «pm» требуют либо окончания «M», либо «».)

Помимо тестовых случаев, я не понимаю синтаксиса, необходимого для возврата значенийМне нужно использовать объект регулярного выражения (список в скобках выше).

1 Ответ

6 голосов
/ 19 июля 2010

Регулярное выражение для этого было бы сложно, и оно также не возвращало бы результаты в ожидаемом порядке в таких случаях, как «Ужин в 9 вечера». Если вы готовы потратить немного времени, было бы проще написать базовый парсер рекурсивного спуска . Каждое слово во входных данных образует токен, и вы можете легко придумать правила, основанные на ваших требованиях. Например:

event: "Dinner" time |
       "Dinner" location |
       "Dinner" time location |
       "Dinner" location time

time:  "at" number ":" number "am"/"pm"
       /* etc. */

Затем вы пишете небольшую функцию для каждого нетерминала (событие, время, местоположение и т. Д.), Которая выполнит свою роль и вернет результат.

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

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