需要有关正则表达式的帮助来解析人类输入时间

Eri*_*ips 1 .net c# regex

我是Regex的新手并且努力工作,但在我看来,这已经超出了简单程度.我知道如何在.Net中创建Regex对象,但是一旦我有了模式,我不确定如何将它用于我的特定目的.

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

我需要能够点一句"晚餐将在晚上9点在你最喜欢的餐厅"并获得价值{"晚餐将在你最喜欢的餐厅","晚上9点"}(如果存在则删除"at").

完整(?)测试用例:

"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" }
Run Code Online (Sandbox Code Playgroud)

(只是为了进一步澄清,没有":"或"am/pm"的数字必须以"at"开头,除非它是列出的第一个数字."am"和"pm"要求以"M"结尾或"".)

除了测试用例之外,我还不了解使用正则表达式对象(上面括号中的列表)获取我需要的值所需的语法.

cas*_*nca 6

执行此操作的正则表达式会很复杂,并且在"晚上9点"等情况下也不会按预期顺序返回结果.如果你愿意花一点时间,那么编写一个基本的递归下降解析器可能会更简单.输入中的每个单词都会形成一个标记,您可以根据自己的要求轻松制定规则.例如:

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

time:  "at" number ":" number "am"/"pm"
       /* etc. */
Run Code Online (Sandbox Code Playgroud)

然后,您将为每个非终端(事件,时间,位置等)编写一个小函数,它将完成其工作并返回结果.

如你所见,你的要求已经提出了很多可能性,正则表达式只会让它变得非常混乱,如果可能的话.