2013-06-04 3 views
2

구문 또는 문장을 읽고 일정/타이밍 정보를 구문 분석 할 문자열 구문 분석기를 작성하고 있습니다. 예를 들어, 입력 문구를C# 동의어가있는 핵심 구문 구문 분석

"하루에 두 번"이 포함될 수 있습니다

또는

"ON 월요일, 수요일, 금요일"

목표는 시작일과 종료일이 주어지면 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

이 문제를 완전히 처리하는 것은 매우 어려운 문제입니다. 내 Natural Language Engine for .NET (https://nuget.org/packages/AboditNLP/)에서 많은 (그러나 전부는 아님) 가능성을 처리합니다.

영어의 모호함이 있습니다. '월요일'은 다음 주 월요일 또는 지난 월요일을 의미 할 수 있습니다.

기본 접근 방식은 날짜 시간을 원하는 값으로 매핑하는 함수를 결합하는 것입니다. 그러나 함수의 출력은 단일 날짜 시간 또는 날짜 시간 범위이거나 날짜 시간 범위 모음이어야합니다 (예 : 2013 년 5 월의 매주 월요일). 사람들이 사용하는 많은 문구가 사실상 무한 범위이며, 다음 문구를 얻기 위해 열거해야 할 수도 있습니다 (예 : 매주 월요일).

영어 DateTime 식은 쿼리 또는 생성 시퀀스를 나타낼 수 있습니다. 데이터베이스 (SQL 또는 LINQ 표현식)에 대한 조회에 대해 원하는 것은 표현식을 달력 항목에 넣을 때 원하는 것과 다를 수 있습니다.

.NET에서 기본 제공되는 Datetime 및 TimeSpan 클래스는 발생할 수있는 대부분의 영어 날짜 시간 표현을 나타내는 데 부적합합니다. 그들은 "2 주"와 같은 공통 간격을 나타낼 방법이 없으며 범위, 컬렉션, 교차점, 조합 및 기타 필요한 모든 조합을 처리 할 수 ​​없습니다.

구문 분석의 관점에서 단순히 왼쪽에서 오른쪽으로 이동할 수 없습니다. 산술처럼, 시간 연산자는 선행 규칙을 가질 수 있습니다. 예를 들어 '지난 5 월의 금요일'은 InfiniteRepeatEveryYear(LastOf(IntersectionOf(all Fridays, all Mays)))으로 처리해야합니다. 예 : '지난 5 월'을 구문 분석해야 '마지막'을 적용 할 수 있습니다.

아주 어려운 문제입니다. 행운을 비네!

+0

다행히도 내 프로젝트의 범위가 훨씬 제한되어 있습니다! 기대되는 출력은 매우 제한된 기간 (나의 목적을 위해 즉각적으로)을 가진 이벤트에 대한 일련의 캘린더 항목입니다. – Otaia