String Haskell处理文件中的文本

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,

大家好,

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, 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