2014-06-08 24 views
2

我正在尝试使用Haskell来处理一些我希望分析的数据。这些数据大部分是结构化的,但并不一致。日期可能有多个表示,尽管总是在同一个地方出现(文档是XML)。解析Haskell中的多种日期格式

的不同格式迄今为止我所看到的是:

。 “周四6月22日1972年”, “第25届1971年2月”

“1973年7月3日”

“10月17日星期四\ r \ n 1974年”

“1976年3月5日星期五”。

“4月25日\ r \ n 1977年”。

“星期二1983年12月6日”

“1988年5月10日”

“1988年10月20日”

我真的不知道从哪里开始 - 任何个人格式,我可以应付,但我不知道如何处理所有这些问题。我想要一个函数String - > Maybe Day。

回答

1

第一件事是一次解决每个问题,并将自己限制在其中一个解析器中。 首先为此解析器编写一些测试。

Haskell中的解析与其他语言中的解析完全不同,通常使用正则表达式或其他方法进行解析。在haskell中,我们有提供解析器组合的优秀库。我使用的是parsecattoparsec

  • 为每个数据类型制作数据类型或使用现有的time -package。

  • 为每个月编写一个解析器(JanFeb ..),然后将它们合并。 但小心,因为MarchMay以相同的字母 开头,你需要的不仅仅是简单的组合。同样是JanuaryJuneJuly

  • 的是有一次很简单的解析器的一些测试(两者的正面和负面的情况下)
  • 写每一天的解析器(第一或第二或第三个相当有帮助真或者第n个)
  • 再结合他们要小心 - 11日和12日与“1”
  • 写了多年

现在解析器同时启动,你应该有Parser DayParser MonthParser Year在手,甚至可能是Parser Weekday

  • 结合这些解析器来形成你有限制自己获得一个Parser Day
  • 现在你应该手头有足够的工具来实现,其余自己

在最后一个音符,有分析器大量的教程parsec/attoparsec那里只是使用你最不信任的搜索引擎。

+1

如果您不是将此作为练习写作,我建议您查看hackage.haskell.org,如果其他人已经实现了这一点,并使您的工作更轻松。 – epsilonhalbe

+0

顺便说一句 - 如果这是不够的信息,只是留下评论 - 我会详细说明一些! – epsilonhalbe

+0

这不是一个练习,我很乐意使用别人的图书馆!你的意思是寻找一些预编解析器的日月等在hackage? – 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 

如果你写一个适当的解析器,你从Control.Applicative免费得到这个替代运算符(<|>)。编写您自己的解析器时,有一个tutorial

我还建议通过消除标点符号甚至是“rd”格式来预处理原始文本,以使其更加健壮并减少您必须编写的解析函数的数量。如果您需要更好的性能,请考虑使用Data.Text