Parsing 在Haskell中解析多个日期格式

Parsing 在Haskell中解析多个日期格式,parsing,date,haskell,Parsing,Date,Haskell,我试图用Haskell来处理一些我想分析的数据。这些数据大多是结构化的,但结构不一致。日期可能有许多表示形式,但总是集中在同一个位置(文档是XML) 到目前为止,我看到的不同格式是: “1971年2月25日” “1972年6月22日星期四。” “1973年7月3日。” “1974年10月17日星期四\r\n” 1976年3月5日,星期五 “1977年4月25日\r\n” “1983年12月6日星期二” “1988年5月10日” “1988年10月20日” 我真的不知道从哪里开始——任何我可以处理

我试图用Haskell来处理一些我想分析的数据。这些数据大多是结构化的,但结构不一致。日期可能有许多表示形式,但总是集中在同一个位置(文档是XML)

到目前为止,我看到的不同格式是:

“1971年2月25日”

“1972年6月22日星期四。”

“1973年7月3日。”

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

1976年3月5日,星期五

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

“1983年12月6日星期二”

“1988年5月10日”

“1988年10月20日”


我真的不知道从哪里开始——任何我可以处理的单独格式,但我不确定如何处理所有这些格式。我想要一个函数字符串->也许是一天。

第一件事是一次解决每个问题,并限制自己使用这些解析器中的一个。 首先为这个解析器编写一些测试

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

  • 为每个或使用现有的-包生成数据类型

  • 为每个月(
    Jan
    Feb
    )编写一个解析器,然后将它们组合起来。 但是要注意,三月和五月都是以同一个字母开头的 你需要的不仅仅是简单的组合。对于
    一月
    六月
    七月

  • 再次对简单的解析器进行一些测试是非常有帮助的(无论是正面的还是负面的)
  • 每天编写一个解析器(第一、第二、第三或第n个)
  • 再次组合它们时要小心-第11和第12个都以“1”开头
  • 多年来一直在编写解析器
现在您应该手头有
解析器日
解析器月
解析器年
,甚至可能还有
解析器工作日

  • 将这些解析器组合起来,形成您限制自己的解析器,以获得一个
    解析器日
  • 现在,您手头应该有足够的实用程序来自己实现其余部分

最后一点,有很多关于
parsec
/
attoprasec
的教程,只要使用你最不信任的搜索引擎就可以了。

有几个关于解析日期的库:

  • 中的
    parseDate
    函数

  • 中的
    parseTime
    函数

然后可以将几个这样的解析器链接在一起。这是一个手动滚动的“备选”操作员:

    -- Chain operator: if p1 returns Nothing, then return p2
    p1 <||> p2 = case p1 of
                   Nothing -> p2
                   Just r -> Just r
然后像这样组合这些:

    parseDate :: String -> Maybe Day
    parseDate = p1 <||> p2 <||> p3
parseDate::String->Maybe Day
parseDate=p1 p2 p3
如果您编写了一个正确的解析器,那么您就可以免费获得这个可选操作符(
),而不受
控制。Applicative
。下面是一篇关于编写自己的解析器的文章


我还建议通过消除标点符号,甚至是“rd”格式来预处理原始文本,以使其更加健壮,并减少您必须编写的解析函数的数量。如果你不把这个作为练习来写,我建议你看看HACKAGE.Haskel.Org,如果其他人已经实现了这一点,让你的工作更容易。BTW——如果这不是足够的信息,只留下一个评论-我会详细说明一些。这不是一个练习,我很想使用别人的图书馆!你的意思是在hackage上为Day-Month等寻找一些预先编写的解析器吗?是的-我认为有人已经解决了这个问题,但这里不是征求建议的地方,所以我想你可以在haskell irc频道或邮件列表上询问。他只是一个候选人
    parseDate :: String -> Maybe Day
    parseDate = p1 <||> p2 <||> p3