我有一个包含此文件的文件:
(Float,Float,Float)"sometext"
(Float,Float,Float)"sometext"
(Float,Float,Float)"sometext"
...
...
我希望我的程序从文件中读取一行,将(Float,Float,Float)放入一个tripple,将“sometext”放入一个String中,并将所有内容放在一个新的数据类型下,这样整个事情就会看起来像这样:
SomeDataType(Float,Float,Float)“sometext”
到目前为止我得到了这个:
readFromDisc filePath = do
fileHandle <- openFile "/tmp/lala.txt" ReadMode
contents <- hGetContents fileHandle
putStrLn $ readOneLine contents
如果文件包含:
(5.0,6.0,7.0)"faraway"
(8.0,9.0,0.0)"holdon"
我明白了:
"(5.0,6.0,7.0)\"faraway\""
现在,因为我把它作为一个字符串,我正在考虑使用
breakInput input = break (=='"') input
要得到这个:
("(5.0,6.0,7.0)","\"faraway\"")
这是一对字符串,我打算使用一些东西来解析tripple和文本,但所有这些都感觉不对。
有更好的方法吗?
答案 0 :(得分:6)
使用reads
功能。它将解析字符串开头的匹配部分,并返回字符串的其余部分。
parseLine :: String -> [((Double, Double, Double), String)]
parseLine line = do
(tuple, line') <- reads line
(string, _) <- reads line'
return (tuple, string)
-- parseLine "(5.0, 6.0, 7.0)\"faraway\"" ---> ((5.0, 6.0, 7.0), "faraway")
这将返回匹配列表,并忽略行尾的垃圾。由于您的特定案例具有明确的解析,因此成功解析只会产生一个匹配。
答案 1 :(得分:0)
readThat (triple, str) = SomeDataType (read triple :: (Float, Float, Float))
(read str :: String)
快速又脏。
答案 2 :(得分:0)
快速破解,如果你不关心处理错误:
data SomeDataType = SomeDataType (Float, Float, Float) String
deriving Read
readOneLine s = read ("SomeDataType " ++ s)