【问题标题】:Haskell - Parsec Parsing <p> elementHaskell - Parsec 解析 <p> 元素
【发布时间】:2010-04-28 20:19:53
【问题描述】:

我正在使用Text.ParserCombinators.ParsecText.XHtml 来解析这样的输入:

这是第一段示例\n 有两行\n \n 这是第二段\n

我的输出应该是:

<p>This is the first paragraph example\n with two lines\n</p> <p>And this is the second paragraph\n</p>

我定义了:


line= do{
        ;t<-manyTill (anyChar) newline
        ;return t
        }

paragraph = do{
        t<-many1 (line) 
        ;return ( p << t )
    }

但它会返回:

<p>This is the first paragraph example\n with two lines\n\n And this is the second paragraph\n</p>

怎么了?有什么想法吗?

谢谢!

【问题讨论】:

    标签: html parsing haskell functional-programming parsec


    【解决方案1】:

    documentation for manyTill 开始,它运行第一个参数0 次或多次,因此连续2 个换行符仍然有效,您的line 解析器不会失败。

    您可能正在寻找类似 @​​987654323@ 的东西(例如 many1many),但它似乎不存在于 Parsec 库中,因此您可能需要自己滚动:(警告:我这台机器上没有 ghc,所以这是完全未经测试的)

    many1Till p end = do
        first <- p
        rest  <- p `manyTill` end
        return (first : rest)
    

    或者更简洁的方式:

    many1Till p end = liftM2 (:) p (p `manyTill` end)
    

    【讨论】:

    • 问题是如果你将它与anyChar 一起使用为p 它仍然匹配两个换行符,因为first &lt;- p 使用了第一个换行符。
    • 作为个人喜好,我会写成:many1Till p end = (:) &lt;$&gt; p &lt;*&gt; manyTill p end。在我看来,do 符号很少改进基于 Parsec 的代码。 (哎呀,没看到你的编辑——liftM2 版本当然和我的一样)
    【解决方案2】:

    manyTill 组合器matches zero or more occurrences of its first argument,根据文档,所以line 会很乐意接受一个空行,这意味着many1 line 将消耗文件中最后一个换行符之前的所有内容,而不是在如您所愿,双换行符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-06
      • 2016-06-19
      • 2016-12-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多