解析Haskell中的特定字符串
问题描述:
我正在使用parsec Haskell库。解析Haskell中的特定字符串
我想解析以下形式的字符串:
[[v1]][[v2]]
xyz[[v1]][[v2]]
[[v1]]xyz[[v2]]
等
我只感兴趣收集的值v1和v2,而这些存储的数据结构。
我试着用下面的代码:
import Text.ParserCombinators.Parsec
quantifiedVars = sepEndBy var (string "]]")
var = between (string "[[") (string "") (many (noneOf "]]"))
parseSL :: String -> Either ParseError [String]
parseSL input = parse quantifiedVars "(unknown)" input
main = do {
c <- getContents;
case parse quantifiedVars "(stdin)" c of {
Left e -> do { putStrLn "Error parsing input:"; print e; };
Right r -> do{ putStrLn "ok"; mapM_ print r; };
}
}
这样,如果输入的是"[[v1]][[v2]]"
程序工作正常,返回下面的输出:
"v1"
"v2"
如果输入"xyz[[v1]][[v2]]"
的程序不起作用。特别是,我只想要[[...]]
中包含的内容,而忽略了"xyz"
。
另外,我想将[[...]]
的内容存储在数据结构中。
你如何解决这个问题?
答
您需要重构解析器。你在非常奇怪的位置使用组合器,他们搞砸了。
A var
是“[[”和“]]”之间的varName
。所以,写:
var = between (string "[[") (string "]]") varName
一个varName
应该有某种形式的(我不认为你要接受“%澶%&”,你呢?),因此你应该做一个解析器为了那个原因;但如果它真的可以是任何东西,只是这样做:
varName = many $ noneOf "]"
然后,将含有瓦尔文本,是一些与非瓦尔分离瓦尔。
varText = someText *> var `sepEndBy` someText
...其中someText
是除外 '[' 什么:
someText = many $ noneOf "["
如果你想这是解析的
事情变得更加复杂:
bla bla [ bla bla [[somevar]blabla]]
然后,你需要一个更好的解析器varName
和someText
:
varName = concat <$> many (try incompleteTerminator <|> many1 (noneOf "]"))
-- Parses e.g. "]a"
incompleteTerminator = (\ a b -> [a, b]) <$> char ']' <*> noneOf "]"
someText = concat <$> many (try incompleteInitiator <|> many1 (noneOf "["))
-- Parses e.g. "[b"
incompleteInitiator = (\ a b -> [a, b]) <$> char '[' <*> noneOf "["
PS。 (<*>)
,(*>)
和(<$>)
来自Control.Applicative
。
所以你想跳过任何没有用[['和']]分隔的东西吗? ''“xyz [[v1]] [[v2]]”''和'“[[v1]] xyz [[v2]]”'都会产生'[“v1”,“v2”]'? – 2012-02-14 14:43:14
它看起来像正则表达式的简单任务。像\\ [\\ [([^]] +)\\] \\]' – Yuras 2012-02-14 22:14:31