Parsec 解析字符串 `sepBy` endline
Parsec parse string `sepBy` endline
我在解析简单字符串时遇到了 parsec
的奇怪行为
字符串示例是:
1 C1 1.1650 2.7470 -0.1840 ca 1 MOL 0.408200
2 N1 -0.0550 2.1750 -0.0380 nb 1 MOL -0.665000
3 C2 -0.2180 0.8450 0.1920 ca 1 MOL 0.450600
4 C3 -1.6310 0.3330 0.3310 c3 1 MOL -0.140700
我的解析器是
atom = do
str <- optional spaces *> (many1 $ (letter <|> digit <|> oneOf "-+.")) `sepBy` spaces
let id = read $ head str :: Int
let charge = (read.head.reverse) str :: Double
return (id,(str !! 1),charge)
records = atom `sepEndBy1` newline
我需要用 atom
解析器解析每个字符串。如果我只对一行使用原子解析器,它就可以工作。
但是如果尝试使用 records
解析器,看起来第一个原子解析器会吃掉整个字符串。所以我有 (1,C1,-0.140700)
而不是数组 [(1,C1,-0.408200),(2,N1,0.665000)]
等
P.S。在这种情况下,我根本无法理解 parsec
如何遍历带有 \n
符号的线。例如,如果我们有
onlyForTest = (many1 $ (letter <|> digit <|> oneOf "-+.")) `sepBy` spaces
并测试这样的例子:
*Main> parseTest onlyForTest "bla bl\na bla"
输出:
["bla","bl","a","bla"]
但是 \n
符号不是 sepBy
!
中的分隔符
正如@freestyle 所说,spaces
使用 Data.Char.isSpace
来确定是否应该消耗一个字符,这包括 \n
和 \r
。
使用 oneOf " \t"
代替 spaces
,使用 endOfLine
代替 newline
。哦,optional
在 optional spaces
中是无关紧要的,因为 spaces
消耗 零个或更多 个字符。
我在解析简单字符串时遇到了 parsec
的奇怪行为
字符串示例是:
1 C1 1.1650 2.7470 -0.1840 ca 1 MOL 0.408200
2 N1 -0.0550 2.1750 -0.0380 nb 1 MOL -0.665000
3 C2 -0.2180 0.8450 0.1920 ca 1 MOL 0.450600
4 C3 -1.6310 0.3330 0.3310 c3 1 MOL -0.140700
我的解析器是
atom = do
str <- optional spaces *> (many1 $ (letter <|> digit <|> oneOf "-+.")) `sepBy` spaces
let id = read $ head str :: Int
let charge = (read.head.reverse) str :: Double
return (id,(str !! 1),charge)
records = atom `sepEndBy1` newline
我需要用 atom
解析器解析每个字符串。如果我只对一行使用原子解析器,它就可以工作。
但是如果尝试使用 records
解析器,看起来第一个原子解析器会吃掉整个字符串。所以我有 (1,C1,-0.140700)
而不是数组 [(1,C1,-0.408200),(2,N1,0.665000)]
等
P.S。在这种情况下,我根本无法理解 parsec
如何遍历带有 \n
符号的线。例如,如果我们有
onlyForTest = (many1 $ (letter <|> digit <|> oneOf "-+.")) `sepBy` spaces
并测试这样的例子:
*Main> parseTest onlyForTest "bla bl\na bla"
输出:
["bla","bl","a","bla"]
但是 \n
符号不是 sepBy
!
正如@freestyle 所说,spaces
使用 Data.Char.isSpace
来确定是否应该消耗一个字符,这包括 \n
和 \r
。
使用 oneOf " \t"
代替 spaces
,使用 endOfLine
代替 newline
。哦,optional
在 optional spaces
中是无关紧要的,因为 spaces
消耗 零个或更多 个字符。