我刚开始使用parsec,我正在尝试做一些简单的事情。
我想分隔键值字符串,如this parsec tutorial。
所示例如,字符串FirstN=Tom&LastN=Brady
应该为[["FirstN","Tom"],["LastN","Brady"]]
。
这很简单,但我还想允许转义字符串中的'='
字符。例如,字符串Equation=1+1\\=2
应该提供[["Equation", "1+1\\=2"]]
(或[["Equation","1+1=2"]]
,但我还没有确定哪个是最好的。)
对于简单示例,解析代码如下:
kvParser :: String -> Either ParseError [[String]]
kvParser input = parse kvString "Error text?" input
kvString = sepBy kvVal (char '&')
kvVal = sepBy (many (noneOf "=&")) (char '=')
要允许转义=
,我认为我需要修改(char '=')
值,但我不确定如何。有没有人有任何建议?
由于
编辑:最终的工作解析器是
kvParser :: String -> Either ParseError [[String]]
kvParser input = parse kvString "Error text?" input
kvString = sepBy kvVal (char '&')
kvVal = sepBy (many kvChar) (char '=')
kvChar = noneOf "\\&=" <|> (char '\\' >> anyChar)
我还使用try
组合器来完成以下工作。
kvParser :: String -> Either ParseError [[String]]
kvParser input = parse kvString "Error text?" input
kvString = sepBy kvVal (char '&')
kvVal = sepBy (many kvChar) (char '=')
kvChar = try (string "\\=" >> return '=') <|> noneOf "&="
答案 0 :(得分:3)
分离器很好;你想要的是接受\=
作为键或值的一部分。而不是
noneOf "=&"
你可以尝试
(noneOf "\\&" <|> (char '\\' >> anyChar))
也就是说,noneOf
将接受任何不是反斜杠的内容,否则右侧的解析器将接受(并跳过)反斜杠并保持跟随它的字符。这应该可以防止它被检测为分隔符。