解析 Parsec 中的转义分隔符

Parsing escaped separation character in Parsec

我刚开始使用 parsec,我正在尝试做一些简单的事情。

我要分隔key-value字符串,如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 "&="

分隔符没问题;您想要的是接受 \= 作为键或值的一部分。而不是

noneOf "=&"

你可以试试

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

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