在解析简单字符串时,我遇到了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
中的分隔符!
答案 0 :(得分:0)
正如@freestyle所说,spaces
使用Data.Char.isSpace
来确定是否应该使用某个字符,并且包括\n
和\r
。
使用oneOf " \t"
代替spaces
和endOfLine
代替newline
。哦,optional
optional spaces
与spaces
无关,因为 @Override
public void onViewDragStateChanged(int state) {
if (state == 0) {
if (settleDestX == contentView.getLeft() && swipeOverListener != null) {
swipeOverListener.onSwipeOver(settlePosition);
}
}
}
消耗零个或多个字符。