String Haskell处理文件中的文本
大家好, 1.我想做什么? 我得到一个带文本的单行文件String Haskell处理文件中的文本,string,haskell,text-processing,String,Haskell,Text Processing,大家好, 1.我想做什么? 我得到一个带文本的单行文件 "Bangabang [Just 3, Nothing, Just 1, Nothing] [Nothing, Nothing, Nothing, Nothing] [Nothing, Nothing, Just 4, Nothing] [Nothing, Just 3, Nothing, Nothing]" 我想从文件中读取此文本并将其转换为: [[Just 3, Nothing, Just 1, Nothing], [Nothing,
"Bangabang [Just 3, Nothing, Just 1, Nothing] [Nothing, Nothing, Nothing, Nothing] [Nothing, Nothing, Just 4, Nothing] [Nothing, Just 3, Nothing, Nothing]"
我想从文件中读取此文本并将其转换为:
[[Just 3, Nothing, Just 1, Nothing], [Nothing, Nothing, Nothing, Nothing], [Nothing, Nothing, Just 4, Nothing], [Nothing, Just 3, Nothing, Nothing]]
这是一种[[可能是整数]]
类型
2.我已经做了什么?
我可以将普通的字符串
修改为可能是整数
我的字符串:
xxx = "Bangabang [Just 3, Nothing, Just 1, Nothing] [Nothing, Nothing, Nothing, Nothing] [Nothing, Nothing, Just 4, Nothing] [Nothing, Just 3, Nothing, Nothing]"
执行stripChars“,]”后,$drop 10 xxx
我得到:
在下一个命令map(splitOn“”)$splitOn“[”
之后,我有:
现在我必须用cleany
最后使用cuty将[[String]]
更改为[[Maybe Integer]]
这就是我想要的
问题是。。。
…如何执行此方法:
parse xxx = cuty $ cleany $ map (splitOn " ") $ splitOn "[" $ stripChars ",]" $ drop 10 xxx
从文件中读取文本时(哪种是IO字符串类型)
这是我的第一个Haskell项目,因此我的功能可能会重新发明轮子或做更糟的事情:/
使用的功能:
main do
文本字符串->字符串
stripChars=filter.flip notElem
--将字符串转换为可能的字符串
maybeRead::读a=>String->maybeRead
maybeRead s=案例读数s
[(x,“”]->仅x
_->没有
--convert(使用子函数conv,因为我不知道如何将其变成一个函数)
conv::[String]->[可能是整数]
conv[]=[]
conv(x:xs)=如果x==“Just”,则conv xs
else maybeRead x:conv xs
转换::[[String]]->[[Maybe Integer]]
转换[]=[]
convert(x:xs)=conv x:convert xs
--cleany(使用子函数clean,因为我不知道如何使它成为一个函数)
清除::[String]->[String]
清洁[]=[]
清除(x:xs)=如果x==“”则清除xs
else x:clean xs
干净::[[String]]->[[String]]
干净的[]=[]
cleany(x:xs)=干净的x:cleany-xs
我假设您可以使用执行零到最小错误检查的解析器。Haskell有很好的解析库,稍后我将用一些您应该了解的替代方法修改我的答案
我建议编写以下函数,而不是使用splitOn
:
takeList :: String -> (String, String)
-- returns the match text and the text following the match
-- e.g. takeList " [1,2,3] ..." returns ("[1,2,3]", " ...")
takeLists :: String -> [String]
-- parses a sequence of lists separated by spaces
-- into a list of matches
我将离开takeList
作为练习。我喜欢使用span
和break
from Data.List来实现这类简单的解析器
关于takeList
,以下是您编写takeList
的方法:
takeLists :: String -> [ String ]
takeLists str =
let s1 = dropWhile (/= '[') str
in if null s1
then []
else let (s2,s3) = takeList s1
in s2 : takeLists s3
例如,takelist“[123][4,5,6][7,8]”
将返回:
[ "[123]", "[4,5,6]", "[7,8]" ]
最后,要将列表中的每个字符串转换为Haskell值,只需使用read
answer :: [ [Int] ]
answer = map read (takeLists " [123] [4,5,6] [7,8] ")
更新
使用基本库中提供的ReadP和ReadS解析器:
import Text.ParserCombinators.ReadP
bang :: ReadP [[Maybe Int]]
bang = do string "Bangabang"
skipSpaces
xs <- sepBy1 (readS_to_P reads) skipSpaces
eof
return xs
input = "Bangabang [Just 3, Nothing, Just 1, Nothing] [Nothing, Nothing, Nothing, Nothing] [Nothing, Nothing, Just 4, Nothing] [Nothing, Just 3, Nothing, Nothing]"
runParser p input = case (readP_to_S p) input of
[] -> error "no parses"
((a,_):_) -> print a
example = runParser bang input
import Text.ParserCombinators.ReadP
bang::ReadP[[Maybe Int]]
bang=do字符串“Bangabang”
滑雪场
xs错误“无解析”
((a),:)->打印a
示例=runParser bang输入
我假设您可以使用执行零到最小错误检查的解析器。Haskell有很好的解析库,稍后我将用一些您应该了解的替代方法修改我的答案
我建议编写以下函数,而不是使用splitOn
:
takeList :: String -> (String, String)
-- returns the match text and the text following the match
-- e.g. takeList " [1,2,3] ..." returns ("[1,2,3]", " ...")
takeLists :: String -> [String]
-- parses a sequence of lists separated by spaces
-- into a list of matches
我将离开takeList
作为练习。我喜欢使用span
和break
from Data.List来实现这类简单的解析器
关于takeList
,以下是您编写takeList
的方法:
takeLists :: String -> [ String ]
takeLists str =
let s1 = dropWhile (/= '[') str
in if null s1
then []
else let (s2,s3) = takeList s1
in s2 : takeLists s3
例如,takelist“[123][4,5,6][7,8]”
将返回:
[ "[123]", "[4,5,6]", "[7,8]" ]
最后,要将列表中的每个字符串转换为Haskell值,只需使用read
answer :: [ [Int] ]
answer = map read (takeLists " [123] [4,5,6] [7,8] ")
更新
使用基本库中提供的ReadP和ReadS解析器:
import Text.ParserCombinators.ReadP
bang :: ReadP [[Maybe Int]]
bang = do string "Bangabang"
skipSpaces
xs <- sepBy1 (readS_to_P reads) skipSpaces
eof
return xs
input = "Bangabang [Just 3, Nothing, Just 1, Nothing] [Nothing, Nothing, Nothing, Nothing] [Nothing, Nothing, Just 4, Nothing] [Nothing, Just 3, Nothing, Nothing]"
runParser p input = case (readP_to_S p) input of
[] -> error "no parses"
((a,_):_) -> print a
example = runParser bang input
import Text.ParserCombinators.ReadP
bang::ReadP[[Maybe Int]]
bang=do字符串“Bangabang”
滑雪场
xs错误“无解析”
((a),:)->打印a
示例=runParser bang输入
您可以直接使用读取
实例
data Bangabang = Bangabang [Maybe Integer]
[Maybe Integer]
[Maybe Integer]
[Maybe Integer] deriving (Read, Show)
现在,您可以使用从类型推断出的所有Read
机制(Read
,reads
,readIO
,…)
readBangabang :: String -> Bangabang
readBangabang = read
如果数据来自文件
readFile "foo.txt" >>= print . readBangabang
您可以直接使用Read
实例
data Bangabang = Bangabang [Maybe Integer]
[Maybe Integer]
[Maybe Integer]
[Maybe Integer] deriving (Read, Show)
现在,您可以使用从类型推断出的所有Read
机制(Read
,reads
,readIO
,…)
readBangabang :: String -> Bangabang
readBangabang = read
如果数据来自文件
readFile "foo.txt" >>= print . readBangabang
请不要用非代码片段分割代码。这只会使复制和粘贴变得笨拙。@Zeta刚刚编辑过。谢谢你的建议!定义data Bangabang=…派生读取
,然后简单地Read
,来解析你的文件。@josejuan谢谢。去阅读有关派生机制和如何使用它的内容吧!@josejuan-派生读取并不完全正确工作-它不会处理数量可变的子列表。请不要将代码与非代码片段分开。这只会使复制和粘贴变得很尴尬。@Zeta刚刚编辑过。谢谢你的建议!定义data Bangabang=…deriving Read
并简单地Read
来解析你的文件。@josejuan谢谢。要阅读关于派生机制a的内容吗nd如何使用它!@josejuan-派生读取不太有效-它不能处理数量可变的子列表。感谢您的回答!我还不熟悉Haskell的解析器:/有一个假设,该文件将始终像“Bangabanga[Just Integer/Nothing][Just Integer/Nothing][Just Integer/Nothing][Just Integer/Nothing][Just Integer/Nothing]“感谢您的更新。它工作得非常好。不幸的是,:type example==IO()
,它必须是[[Maybe Integer]]]
,因为它以后将与另一个函数一起使用;(只需将print a
更改为a
。感谢您的回复!我还不熟悉Haskell的解析器:/有一个假设,该文件总是像“Bangabanga[Just Integer/Nothing][Just Integer/Nothing][Just Integer/Nothing][Just Integer/Nothing][Just Integer/Nothing][Just Integer/Nothing]”感谢您的更新。它工作得非常好。Un