【问题标题】:Parsing multiple date formats in Haskell在 Haskell 中解析多种日期格式
【发布时间】:2014-06-08 08:19:00
【问题描述】:

我正在尝试使用 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 日”

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

【问题讨论】:

    标签: parsing date haskell


    【解决方案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 免费获得这个替代运算符 (&lt;|&gt;)。这是关于编写自己的解析器的tutorial。

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

    【讨论】:

      【解决方案2】:

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

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

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

      • 为每个月编写一个解析器(Jan 或Feb..),然后将它们组合起来。 但请注意 March 和 May 都以相同的字母开头 您需要的不仅仅是简单的组合。 January、June 和 July 也是如此

      • 再次对简单解析器进行一些测试非常有帮助(针对正例和负例)
      • 为每一天(第 1 天或第 2 天或第 3 天或第 n 天)编写一个解析器
      • 再次组合它们时要小心 - 11th 和 12th 都以 '1' 开头
      • 多年编写解析器

      现在您应该拥有Parser Day、Parser Month 和Parser Year,甚至可能是Parser Weekday。

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

      最后一点,有很多parsec/attoparsec 的教程,只需使用您最不信任的搜索引擎即可。

      【讨论】:

      • 如果你不是把这个写成练习,我建议你看看 hackage.haskell.org 如果其他人已经实现了这个并且让你的工作更容易。
      • 顺便说一句 - 如果这还不够信息,请发表评论 - 我会详细说明!
      • 这不是一个练习,我很想使用别人的图书馆!你的意思是在hackage上寻找一些预写的解析器日月等?
      • 是的 - 我想有人已经解决了这个问题,但这里不是寻求建议的地方,所以我想你可以在#haskell irc 频道或邮件列表中询问。 this 只是一名候选人
      猜你喜欢
      • 2013-01-09
      • 2020-09-14
      • 2020-07-04
      • 1970-01-01
      • 2011-05-09
      • 2018-02-07
      • 2018-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多