在Parsec中解析逃逸的分离角色

时间:2016-06-20 06:39:14

标签: haskell parsec

我刚开始使用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 "&="

1 个答案:

答案 0 :(得分:3)

分离器很好;你想要的是接受\=作为键或值的一部分。而不是

noneOf "=&"
你可以尝试

(noneOf "\\&" <|> (char '\\' >> anyChar))

也就是说,noneOf将接受任何不是反斜杠的内容,否则右侧的解析器将接受(并跳过)反斜杠并保持跟随它的字符。这应该可以防止它被检测为分隔符。