用同义词解析关键短语



我正在研究一个字符串解析器,它将读取一个短语或句子并解析它的时间表/定时信息。例如,输入可能包括短语

"每日两次"

"ON MONDAY, WEDNESDAY AND FRIDAY"

目标是创建一个模板,当给定开始和结束日期时,该模板可以转换为DateTimes列表。我想过将此模板存储为Func<DateTime, bool>:

前一个例子可能被解释为(d => d.TimeOfDay == TimeSpan.FromHours(8) || d.TimeOFDay == TimeSpan.FromHours(18))或任何最有意义的时间

后一个例子可以解释为(d => d.TimeOfDay == TimeSpan.FromHours(8) && (d.DayOfWeek == Monday || d.DayOfWeek == Wednesday || d.DayOfWeek == Friday))

然后,我可以循环遍历开始日期和结束日期之间的每个小时,如果函数返回true,则将时间添加到计划中。

我遇到的问题是解析。我目前的解决方案是创建一个字典,其中包含我可能期望的所有短语,并将适当的过滤器作为值。然而,这开始看起来非常混乱和不可持续,特别是可能有大量的重叠:

var phrases = new Dictionary<string, Func<DateTime, bool>>()
{
    { "DAILY", (d => true) },
    { "A DAY", (d => true) },
    { "PER DAY", (d => true) },
    { "EVERY DAY", (d => true) },
    { "SUNDAY", (d => d.DayOfWeek == DayOfWeek.Sunday) },
    { "SUN", (d => d.DayOfWeek == DayOfWeek.Sunday) },
    { "MONDAY", (d => d.DayOfWeek == DayOfWeek.Monday) },
    { "MON", (d => d.DayOfWeek == DayOfWeek.Monday) },
    . . .
}

有什么更好的方法来做到这一点?

要完全处理这是一个非常困难的问题。我在我的。net自然语言引擎(https://nuget.org/packages/AboditNLP/)中处理了许多(但不是全部)可能性。

其中一个挑战是英语是模棱两可的:'MONDAY'可以根据上下文表示这个星期一,下星期一或上星期一。

你的基本方法是一个好方法:组合函数将日期时间映射到所需的值。但是该函数的输出可能需要是单个日期时间或日期时间范围,或日期时间范围的集合(例如,2013年5月的每个星期一)。还有许多人们使用的短语实际上是一个无限的范围,你可能需要列举这些来得到下一个(或几个)(例如每周一)。

英文DateTime表达式既可以表示查询,也可以表示生成序列。对数据库的查询(SQL或LINQ表达式)所需的内容可能与将表达式放入日历条目时所需的内容非常不同。 . net中内置的Datetime和TimeSpan类不足以表示您将遇到的大多数英语日期时间表达式。它们无法表示常见的间隔,如"两周",也不能处理范围、集合、交集、并集和所有其他你需要的组合。

从解析的角度来看,不能简单地从左到右。与算术一样,时间运算符也可能具有优先规则。例如,"the last Friday in May"确实需要作为InfiniteRepeatEveryYear(LastOf(IntersectionOf(all Fridays, all Mays)))处理,即:"Friday in May"需要在对其应用"the last"之前进行解析。

这是一个很难的问题,祝你好运!

最新更新