haskell - 为什么当行尾序列是 CRLF 时这个解析器总是失败?

标签 haskell attoparsec end-of-line

这个简单的解析器预计会解析以下形式的消息

key: value\r\nkey: value\r\n\r\nkey: value\r\nkey: value\r\n\r\n

一个 EOL 作为字段分隔符,两个 EOL 作为消息分隔符。当 EOL 分隔符为 \n 时它工作得很好,但当 \r\nparseWith 总是返回失败。

parsePair = do
  key <- B8.takeTill (==':')
  _ <- B8.char ':'
  _ <- B8.char ' '
  value <- B8.manyTill B8.anyChar endOfLine
  return (key, value)

parseListPairs = sepBy parsePair endOfLine <* endOfLine

parseMsg = sepBy parseListPairs endOfLine <* endOfLine

最佳答案

我假设您正在使用这些导入:

{-# LANGUAGE OverloadedStrings #-}
import qualified Data.Attoparsec.ByteString.Char8 as B8
import Data.Attoparsec.ByteString.Char8

问题是 endOfLine 消耗了行尾,所以也许你真的想要这样的东西:

parseListPairs = B8.many1 parsePair <* endOfInput

例如,这有效:

ghci> parseOnly parseListPairs "k: v\r\nk2: v2\r\n"
Right [("k","v"),("k2","v2")]

更新:

要解析多条消息,您可以使用:

parseListPairs = B8.manyTill parsePair endOfLine
parseMsgs = B8.manyTill parseListPairs endOfInput

ghci> test3 = parseOnly parseMsgs "k1: v1\r\nk2: v2\r\n\r\nk3: v3\r\nk4: v4\r\n\r\n"
Right [[("k1","v1"),("k2","v2")],[("k3","v3"),("k4","v4")]]

关于haskell - 为什么当行尾序列是 CRLF 时这个解析器总是失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32368392/

相关文章:

C++ - 使用 >> 运算符读取文件直到到达行尾

haskell - 了解 STG

git - SourceTree App 说即使对于新克隆的存储库也有未提交的更改 - 可能有什么问题?

haskell - 类似于 (>>=) 的函数,但返回不同的 monad

parsing - 使用 attoparsec 对解析后的数据进行操作

haskell - 如何正确地将 IO 添加到 attoparsec Parser?

haskell - 为什么图书馆设计者在 Text 似乎合适的地方使用 ByteString?

Laravel Seeder 中的 PHP_EOL 问题

haskell - Haskell 是否进行从 double 到整数的默认转换?

haskell - 通用类型默认规则