Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String Haskell中的字符串解析_String_Parsing_Haskell - Fatal编程技术网

String Haskell中的字符串解析

String Haskell中的字符串解析,string,parsing,haskell,String,Parsing,Haskell,我是Haskell的新手,目前正在尝试解决一个需要一些字符串解析的问题。我的输入字符串包含以逗号分隔的引号中的单词列表。我想把这个字符串解析成一个字符串形式的单词列表。我应该从哪里开始学习解析这样的字符串?是否有一个partuclar模块和/或功能会有所帮助 p、 请不要发布完整的解决方案。我只是想要一个指向起始位置的指针,这样我就可以学习如何操作。因为Strings只是Haskell中Chars的列表,所以这是一个开始寻找的好地方(为了学习Haskell) 对于更复杂的情况(例如,逗号可能嵌套

我是Haskell的新手,目前正在尝试解决一个需要一些字符串解析的问题。我的输入字符串包含以逗号分隔的引号中的单词列表。我想把这个字符串解析成一个字符串形式的单词列表。我应该从哪里开始学习解析这样的字符串?是否有一个partuclar模块和/或功能会有所帮助


p、 请不要发布完整的解决方案。我只是想要一个指向起始位置的指针,这样我就可以学习如何操作。

因为
String
s只是Haskell中
Char
s的列表,所以这是一个开始寻找的好地方(为了学习Haskell)

对于更复杂的情况(例如,逗号可能嵌套在引号内,应该忽略),(如Daniel所述)将是更好的解决方案


另外,如果你想解析CSV,你可以试试,尽管我还没有尝试过,所以我不能说它有多大帮助。

为了给那些遇到这个问题的人一个完整的答案,它还有一些很好的功能。

对于任何“真正的工作”都使用parsec


要了解简介,请阅读以下一种特别厚颜无耻的方式:

parseCommaSepQuotedWords :: String -> [String]
parseCommaSepQuotedWords s = read ("[" ++ s ++ "]")
这可能有效,但它非常脆弱,而且相当愚蠢。实际上,您使用的是Haskell编写字符串列表的方式几乎与您的方式一致,因此内置的
Read
实例几乎就是您想要的。您可以使用
reads
来更好地报告错误,但实际上,您可能希望完全执行其他操作

总的来说,
parsec
确实值得一看——这是一种使用的乐趣,也是最初让我对Haskell感到兴奋的事情之一。但是,如果您想要一个自主开发的解决方案,我通常会使用
case
语句对
span
break
的结果编写简单的东西。假设您正在输入中查找下一个分号。然后
中断(=';')inp
将返回
(之前、之后)
,其中:

  • before
    inp
    的内容,最多(不包括)第一个分号(如果没有分号,则为全部分号)
  • 之后是字符串的其余部分:
    
    • 如果
    之后的
    不是空的,则第一个元素是分号
  • 无论发生什么情况,
    before++after==inp
因此,要解析由分号分隔的语句列表,我可以这样做:

parseStmts :: String -> Maybe [Stmt]
parseStmts inp = case break (== ';') inp of
  (before, _ : after) -> -- ...
    -- ^ before is the first statement
    --     ^ ignore the semicolon
    --           ^ after is the rest of the string
  (_, []) -> -- inp doesn't contain any semicolons

最强大的解决方案是解析器组合器。Haskell有几个,但我想到的最重要的是:

  • :一个非常好的通用解析库
  • :更快版本的parsec,它牺牲了错误消息的质量和一些其他功能以获得更高的速度
  • :一个非常强大的解析库
解析器组合器的最大优点是,使用
do
符号(或者
Applicative
样式,如果您愿意的话)定义解析器非常容易


如果您只需要一些快速简单的字符串操作功能,请查阅
文本
库(用于高性能字节编码字符串)或
数据.List
(用于普通列表编码字符串),它提供了必要的函数来操作字符串。

我最终决定使用自己的解析函数,因为这是一种非常简单的情况。自从我第一次发布这个问题并想在这里记录我的解决方案以来,我对Haskell了解了很多:

split :: Char -> String -> [String]
split _ "" = []
split c s = firstWord : (split c rest)
    where firstWord = takeWhile (/=c) s
          rest = drop (length firstWord + 1) s

removeChar :: Char -> String -> String
removeChar _ [] = []
removeChar ch (c:cs)
    | c == ch   = removeChar ch cs
    | otherwise = c:(removeChar ch cs)

main = do
    handle <- openFile "input/names.txt" ReadMode
    contents <- hGetContents handle
    let names = sort (map (removeChar '"') (split ',' contents))
    print names
    hClose handle
split::Char->String->[String]
拆分“=[]
拆分c s=第一个字:(拆分c剩余)
其中firstWord=takeWhile(/=c)s
剩余=下降(长度第一个字+1)s
removeChar::Char->String->String
removeChar[]=[]
removeChar ch(c:cs)
|c==ch=removeChar ch cs
|否则=c:(移除向量ch cs)
main=do

句柄可能会有用。或者你可以使用真正的解析器,比如。听起来像是用逗号和引号分隔的?@BenMillwood这些单词被引号包围,用逗号分隔。当我还是一个noob的时候,我无法理解uu parsinglib的头尾。从那以后我再也没有尝试过,但我并不认为它是友好的;见第二节。5.2系列中的其他链接和其他资源