2014-06-08 2 views
2

Я пытаюсь использовать Haskell для обработки некоторых данных, которые я хочу проанализировать. Эти данные в основном структурированы, но непоследовательно. Даты могут иметь несколько представлений, хотя всегда опираются на одно и то же место (документы - это XML).Разбор нескольких форматов даты в Haskell

Отличающиеся форматы, которые я видел до сих пор являются:

"25 февраля 1971"

"Четверг 22 июня 1972 года.".

"3 июля 1973."

«Четверг, 17 октября 1974 года».

«Пятница, 5 марта 1976 года».

«25 апреля 1977 года».

"Вторник 6 декабря 1983"

"10 мая 1988"

"20 октября 1988"

Я не знаю, с чего начать - любой индивидуальный формат, я мог бы иметь дело с, но я не уверен, как бороться со всеми из них. Мне нужна функция String -> Maybe Day.

ответ

1

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

Анализ в Haskell отличается от разбора на других языках, обычно используется регулярные выражения или другие средства. В haskell у нас есть отличные библиотеки, которые обеспечивают комбинаторы парсеров. Я использовал parsec и attoparsec.

  • Создание типа данных для каждого или использовать существующий time -package.

  • написать парсер на каждый месяц (Jan или Feb ..) а затем комбинировать их. Но обратите внимание, что и March, и May начинаются с того же письма вам нужно больше, чем простое сочетание. То же самое верно и для January, June и July

  • это вполне полезно снова несколько тестов для простых парсеров (как для положительных и отрицательных случаев)
  • написать синтаксический анализатор на каждый день (1-й или 2-й или 3-й или п-я)
  • объединить их снова быть осторожным - 11 и 12 начинают как с «1»
  • написать парсер лет

Теперь вы должны иметь Parser Day, Parser Month и Parser Year под рукой и, возможно, даже Parser Weekday.

  • объединить эти парсеры, чтобы сформировать парсер вы ограничили себя, чтобы получить Parser Day
  • теперь вы должны иметь достаточно утилиты под рукой, чтобы реализовать все остальное себя

На последней ноте, есть большое количество учебных пособий для parsec/attoparsec там просто используйте поисковую систему вашего наименьшего недоверия там.

+1

Если вы не пишете это как упражнение, я бы порекомендовал вам взглянуть на hackage.haskell.org, если кто-то еще это осуществил и облегчил вашу работу. – epsilonhalbe

+0

btw - если этого недостаточно, просто оставьте комментарий - я уточню еще кое-что! – epsilonhalbe

+0

Это не как упражнение, и я хотел бы использовать библиотеку кого-то elses! Вы хотите найти некоторые предварительно написанные синтаксические анализаторы для Day Month и т. Д. В случае взлома? – oneway

1

Есть несколько библиотек на hackage для разбора дат:

Затем вы можете связать несколько таких парсеров. Вот скрученные вручную «альтернативный» оператор:

-- Chain operator: if p1 returns Nothing, then return p2 
    p1 <||> p2 = case p1 of 
        Nothing -> p2 
        Just r -> Just r 

Таким образом, вы бы написать функцию разбора для каждого формата:

p1 :: String -> Maybe Day 

Затем объединить их так:

parseDate :: String -> Maybe Day 
    parseDate = p1 <||> p2 <||> p3 

Если вы пишете правильный Parser, вы получаете этого альтернативного оператора (<|>) бесплатно от Control.Applicative. Вот tutorial о написании собственных парсеров.

Я бы также рекомендовал предварительно обработать необработанный текст, исключив знаки препинания и, возможно, даже «rd», чтобы сделать его более надежным и сократить количество функций синтаксического анализа, которые вам придется писать. Также рассмотрите возможность использования Data.Text, если вам нужна более высокая производительность.

Смежные вопросы