Гибкие стратегии синтаксического анализа текста

Проблема

Я пытаюсь найти гибкий способ анализа содержимого электронной почты. Ниже приведен пример фиктивного текста электронного письма, с которым я работаю. Я' Я также хотел бы избегать регулярных выражений, если это вообще возможно. Однако на данном этапе процесса решения проблем я начинаю думать, что это неизбежно. Обратите внимание, что это лишь небольшая фиктивная часть полного электронного письма. Мне нужно проанализировать каждое поле (например, номер билета, сотовый телефон) на соответствующие типы данных. Наконец, присутствие некоторых полей в электронном письме не гарантируется (в моем текущем решении, показанном ниже, вы увидите, почему это проблема).

Header Code:EMERGENCY                               
Ticket No:   123456789 Seq. No: 2
Update of:             

Original Call Date:     01/02/2011     Time:      11:17:03 AM  OP: 1102
Second Call Date:     01/02/2011     Time:      12:11:00 AM  OP: 

Company:           COMPANY NAME
Contact:      CONTACT NAME          Contact Phone: (111)111-1111
Secondary Contact: SECONDARY CONTACT
Alternate Contact:                       Altern. Phone:                  
Best Time to Call: AFTER 4:30P           Fax No:        (111)111-1111
Cell Phone:                              Pager No:                       
Caller Address: 330 FOO
                FOO AVENUE 123

Текущее решение

В этом простом примере я успешно могу проанализировать большинство полей с функцией ниже.

private T BetweenOperation<T>(string emailBody, string start, string end)
{
 var culture = StringComparison.InvariantCulture;
 int startIndex =
  emailBody.IndexOf(start, culture) + start.Length;
 int endIndex =
  emailBody.IndexOf(end, culture);
 int length = endIndex - startIndex;

 if (length < 0) return default(T);

 return (T)Convert.ChangeType(
  emailBody.Substring(startIndex, length).Trim(), 
  typeof(T));
}

По сути, моя идея заключалась в том, чтобы я мог анализировать содержимое между двумя полями. Например, я мог бы код заголовка, выполнив

// returns "EMERGENCY"
BetweenOperation<string>("email content", "Header Code:", "Ticket No:")

Этот подход, однако, имеет много недостатков. Один большой недостаток заключается в том, что поле end не всегда присутствует. Как вы можете видеть, есть несколько похожих ключей с идентичными ключевыми словами, которые не анализируются должным образом, например «Контакт» и «Дополнительный контакт». Это заставляет парсер извлекать слишком много информации. Кроме того, если мое конечное поле отсутствует, я получу непредсказуемый результат. Наконец, я могу проанализировать целые строки, чтобы затем передать их BetweenOperation , используя это.

private string LineOperation(string startWithCriteria)
{
    string[] emailLines = EmailBody.Split(new[] { '\n' });

    return 
        emailLines.Where(emailLine => emailLine.StartsWith(startWithCriteria))
        .FirstOrDefault();
}

Мы могли бы использовать LineOperation в некоторых случаях, когда имя поля не является уникальным (например, Time) и передать результат в BetweenOperation .

Вопрос

Как можно проанализировать показанный выше контент на основе ключей. Например, клавиши «Код заголовка» и «Сотовый телефон». Обратите внимание, что я не думаю, что синтаксический анализ основан на пробелах вкладок, потому что некоторые поля могут быть длиной в несколько строк (например, Адрес вызывающего абонента) или вообще не содержат значения (например, Альтернативный телефон).

Спасибо.

5
задан Mike 28 January 2011 в 18:42
поделиться