Parsing escaped separation character in Parsec
我刚开始使用 parsec,我正在尝试做一些简单的事情。
我想分隔键值字符串,如本解析教程中所示。
例如,字符串 FirstN=Tom&LastN=Brady 应该给出 [["FirstN","Tom"],["LastN","Brady"]].
这很容易,但我也想允许字符串中的 '=' 字符被转义。例如,字符串 Equation=1+1\\\\=2 应该给出 [["Equation","1+1\\\\=2"]] (或 [["Equation","1+1=2"]] 但我还没有决定哪个最好)。
对于简单的例子,解析代码如下:
1 2 3 4 5
| kvParser :: String -> Either ParseError [[String]]
kvParser input = parse kvString "Error text?" input
kvString = sepBy kvVal (char ' &' )
kvVal = sepBy (many (noneOf "=&")) (char ' =' ) |
为了允许转义 = 我想我需要修改 (char '=') 值,但我不确定如何。有人有什么建议吗?
谢谢
编辑:最终的工作解析器是
1 2 3 4 5 6
| 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 组合器完成了以下工作。
1 2 3 4 5 6
| 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
| (noneOf"\\\\&" <|> (char '\\\' >> anyChar)) |
也就是说,noneOf 将接受任何不是反斜杠的内容,否则右侧的解析器将接受(并跳过)反斜杠并保持字符跟随它。这应该可以防止它被检测为分隔符。
- 我用 (noneOf"\\\\&" <|> (char \\\\ >> anyChar)) 替换了 noneOf"=&" 但现在它根本没有在 = 上分开。不过,它确实吃掉了 `\\\\\\\\\\\\\\\\` 的值。
-
好的,也许您需要将 = 添加回 noneOf 字符串。我承认我还没有亲自测试过。我认为 noneOf"\\\\=&" 会工作......