Html Haskell-Parsec解析<;p>;要素

Html Haskell-Parsec解析<;p>;要素,html,parsing,haskell,functional-programming,parsec,Html,Parsing,Haskell,Functional Programming,Parsec,我使用and来解析这样的输入: This is the first paragraph example\n with two lines\n \n And this is the second paragraph\n 这是第一段示例\n 有两行\n \n 这是第二段\n 我的输出应该是: 这是第一段示例\n 有两行\n 这是第二段\n 我定义: line= do{ ;t<-manyTill (anyChar) newline ;return t

我使用and来解析这样的输入:

This is the first paragraph example\n with two lines\n \n And this is the second paragraph\n 这是第一段示例\n 有两行\n \n 这是第二段\n 我的输出应该是:


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

这是第二段\n

我定义:


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

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


line=do{

根据文档,tmanyTill
combinator,因此
将乐意接受一个空行,这意味着
many1行
将消耗文件中直到最后一个换行的所有内容,而不是像预期的那样停在一个双换行处。

从开始,它运行第一个参数0或m多次,所以一行中有两行换行符仍然有效,并且您的
解析器不会失败

您可能正在寻找类似于
many1Till
(例如
many1
many
)的内容,但它似乎不存在于Parsec库中,因此您可能需要自己进行滚动:(警告:我在这台机器上没有ghc,因此这是完全未经测试的)


问题是,如果将它与
anyChar
as
p
一起使用,它仍然匹配两个换行符,因为
首先作为个人偏好,我会将其写成:
many1Till p end=(:)p manyTill p end
。在我看来,
do
符号很少改进基于Parsec的代码。(哎呀,没有看到你的编辑——
liftM2
版本当然与我的版本相当)
many1Till p end = do
    first <- p
    rest  <- p `manyTill` end
    return (first : rest)
many1Till p end = liftM2 (:) p (p `manyTill` end)