2

フレーズまたは文を読み取り、スケジュール/タイミング情報を解析する文字列パーサーに取り組んでいます。たとえば、入力には次のフレーズが含まれる場合があります。

「1日2回」

また

「月曜日、水曜日、金曜日」

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))

次に、開始日と終了日の間を 1 時間ごとにループし、関数が 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) },
    . . .
}

これを行うためのより良い方法は何ですか?

4

1 に答える 1

0

これを完全に処理するのは非常に難しい問題です。.NET 用の自然言語エンジン ( https://nuget.org/packages/AboditNLP/ ) で多くの (すべてではない) 可能性を処理します。

課題の 1 つは、英語があいまいであることです。'MONDAY' は、文脈に応じて、今週の月曜日、次の月曜日、または先週の月曜日を意味する場合があります。

あなたの基本的なアプローチは良いものです: 日時を目的の値にマップする関数を組み合わせます。ただし、関数の出力は、単一の日付時刻または日付時刻範囲、または日付時刻範囲のコレクション (2013 年 5 月の毎週月曜日など) である必要がある場合があります。また、実際には無限の範囲で使用される多くのフレーズがあり、次の 1 つ (または複数) を取得するためにこれらを列挙する必要がある場合があります (毎週月曜日など)。

英語の DateTime 式は、クエリまたは生成シーケンスのいずれかを表現できます。データベースに対するクエリ (SQL または LINQ 式) に必要なものは、式をカレンダー エントリに入れるときに必要なものとは大きく異なる場合があります。

.NET の組み込みの Datetime および TimeSpan クラスは、遭遇するほとんどの英語の日時表現を表すには不十分です。「2週間」のような一般的な間隔を表す方法がなく、範囲、コレクション、交差、結合、および必要な他のすべての組み合わせを処理できません。

解析の観点からは、単純に左から右に進むことはできません。算術演算と同様に、一時演算子には優先順位規則がある場合があります。たとえば、「5 月の最後の金曜日」は実際には として処理する必要がありますInfiniteRepeatEveryYear(LastOf(IntersectionOf(all Fridays, all Mays)))。つまり、「5 月の金曜日」は、「最後の」を適用する前に解析する必要があります。

とても難しい問題です、がんばってください!

于 2013-06-04T16:07:32.247 に答える