我有一个类似Java的属性文本文件,带有键值对。将这些数据加载到haskell然后访问它的有什么好方法。
文件看起来像:
XXXX=vvvvv
YYYY=uuuuu
我希望能够访问“XXXX”键。
答案 0 :(得分:4)
您可以使用解析器库,例如优秀的Parsec(Haskell平台的一部分)。为简单的格式编写解析器只需几分钟。
然而,如果它真的那么简单,你可以使用split;使用标准lines
函数将字符串拆分为行(如果需要处理空行等,则使用Data.List.Split),然后使用Data.List.Split函数将其拆分为{{ 1}}。
最简单的解决方案是使用break
滚动自己:
'='
但是,这不会处理空格,空行或类似的内容。
至于按键查找,一旦你有import Control.Arrow
parse :: String -> [(String, String)]
parse = map parseField . lines
where parseField = second (drop 1) . break (== '=')
之类的结构,很容易将它放入Map(fromList
)并对其进行操作。
答案 1 :(得分:1)
探索ehird未提及的一些细节,以及略有不同的方法:
import qualified Data.Map as Map
type Key = String
type Val = String
main = do
-- get contents of file (contents :: String)
contents <- readFile "config.txt"
-- split into lines (optionList :: [String])
let optionList = lines contents
-- parse into map (optionMap :: Map Key Val)
let optionMap = optionMapFromList optionList
doStuffWith optionMap
optionMapFromList :: [String] -> Map.Map Key Val
optionMapFromList = foldr step Map.empty
where step line map = case parseOpt line of
Just (key, val) -> Map.insert key val map
Nothing -> map
parseOpt :: String -> Maybe (Key, Val)
parseOpt = undefined
我已经将您的问题解决方案表达为 fold :获取文件中的行列表,并将其转换为所需的地图。折叠的每个step
包括检查单行,尝试将其解析为键/值对,并在成功时将其插入到地图中。
我离开parseOpt
未定义;你可以使用像ehird parseField
这样的方法,或者你喜欢的任何方法。也许你更愿意只解析特定的选项:
interestingOpts = ["XXXX", "YYYY"]
parseOpt line = case find (`isPrefixOf` line) interestingOpts of
Just key -> Just (key, drop 1 $ dropWhile (/= '=') line)
Nothing -> Nothing
如果你有(例如)选项“XX”和选项“XXXX”,使用前缀测试方法并不总是最好的想法。四处游走,看看哪种方法最适合您的数据。如果您需要高性能,请使用Data.Text代替String
s。