2013-06-04 97 views
2

我正在研究一個字符串解析器,它將讀取一個短語或句子,並解析它的計劃/時間信息。例如,輸入可能包括短語C#解析關鍵短語與同義詞

「兩次,每天」

「在星期一,星期三和星期五」

的目標是創建一個模板,該模板在給定開始日期和結束日期時可以轉換爲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) }, 
    . . . 
} 

什麼是更好的方式來做到這一點?

+1

可能想看看自然語言處理。 –

+0

它可能有助於編寫/實現DFA(確定性有限自動機)。你從「開始狀態」開始,然後遍歷句子中的每個單詞,並根據單詞如何影響句子的「種類」,轉換到新狀態(或回到當前狀態)。你將不得不提出這些轉換的規則。 –

+0

看看這個:http://www.codeproject.com/Articles/38553/TaskScheduler –

回答

0

要完全處理這是一個非常困難的問題。我在.NET的Natural Language Engine(https://nuget.org/packages/AboditNLP/)中處理了許多(但不是全部)的可能性。

其中一個挑戰是英語不明確:「星期一」可能意味着本週一,下週一或上週一取決於上下文。

您的基本方法是一個很好的方法:結合將日期時間映射到期望值的函數。但是,該功能的輸出可能需要是單個日期時間或日期時間範圍,或日期時間範圍的集合(例如,2013年5月的每個星期一)。也有很多人使用的短語實際上是無限的範圍,你可能需要列舉下一個(或幾個)(例如每個星期一)。

英語DateTime表達式可以表示查詢或生成序列。對數據庫查詢(SQL或LINQ表達式)所需的內容可能與將表達式放入日曆條目時所需的內容非常不同。

.NET中內建的Datetime和TimeSpan類不足以表示您將遇到的大多數英語日期時間表達式。他們無法像「兩週」那樣表示常見間隔,並且無法處理範圍,集合,交集,聯合以及您需要的所有其他組合。

從解析的角度來看,你不能簡單地從左到右。像算術一樣,時間運算符可能有優先規則。例如,「5月的最後一個星期五」確實需要作爲InfiniteRepeatEveryYear(LastOf(IntersectionOf(all Fridays, all Mays)))來處理,即「5月星期五」需要被解析,然後才能應用「最後一個」。

這是一個非常難的問題,祝你好運!

+0

幸運的是,我的項目範圍遠不止於此!期望的輸出總是一系列日曆條目,用於持續時間非常有限的事件(即時用於我的目的)。 – Otaia