解析我很新的Haskell和我目前正在努力解决需要一些字符串分析的一个问题。我的输入字符串包含逗号分隔的引号中的单词列表。我想将这个单个字符串解析为字符串的列表,作为字符串。我应该从哪里开始学习解析这样的字符串?是否有一个partuclar模块和/或功能会有帮助?字符串在Haskell
p.s.请不要发布完整的解决方案。我只是要求一个指针开始的地方,所以我可以学习如何做到这一点。
解析我很新的Haskell和我目前正在努力解决需要一些字符串分析的一个问题。我的输入字符串包含逗号分隔的引号中的单词列表。我想将这个单个字符串解析为字符串的列表,作为字符串。我应该从哪里开始学习解析这样的字符串?是否有一个partuclar模块和/或功能会有帮助?字符串在Haskell
p.s.请不要发布完整的解决方案。我只是要求一个指针开始的地方,所以我可以学习如何做到这一点。
在具有为那些谁碰巧就这个问题一个完整的答案的利益,Data.Text有一些很好的功能,以及。
任何东西使用秒差距即是“真正的工作”。
此链接现在位于http://therning.org/magnus/posts/2007-05-27-289-adventures-in-parsing.html;请参阅https://wiki.haskell.org/Parsec Sec。 5.2系列中的其他链接和其他资源 –
下面就来进行一个特别厚脸皮方式:
parseCommaSepQuotedWords :: String -> [String]
parseCommaSepQuotedWords s = read ("[" ++ s ++ "]")
这可能会实现,但它是很脆弱的,很愚蠢。本质上你使用的是Haskell编写字符串列表几乎几乎与你的方式相符的事实,因此内置的Read
实例是几乎你想要的东西。你可以使用reads
更好的错误报告,但在现实中,你可能想要做完全是另一回事。
一般来说,parsec
是真的值得一看 - 这是一个喜悦使用,并且最初真正让我兴奋的事情之一是Haskell。但是如果你想要一个自己开发的解决方案,我经常使用case
语句对span
和break
的结果编写简单的东西。假设您正在寻找输入中的下一个分号。然后break (== ';') inp
将返回(before, after)
,其中:
before
是inp
到内容(不包括)第一个分号(或全部,如果都没有)after
是字符串的其余部分:
after
不为空,第一个元素是一个分号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有这几条,但是,我想起最重要的是:
解析器组合的一大优点是,它是非常容易使用定义解析器do
表示法(或Applicative
风格,如果您愿意)。
如果你只是想要一些快速和简单的字符串处理功能,然后咨询text
库(用于高性能字节编码字符串),或Data.List
(普通列表的编码字符串),它提供了必要的功能来操纵字符串。
当我是一个noob时,我无法制作uu-parsinglib的正面和反面。从那以后,我还没有尝试过,但我不完全称它为友好。 –
我终于决定推出我自己的解析函数,因为这是一个很简单的情况。我已经学到了很多关于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](http://hackage.haskell.org/package/split)很可能是有用的。或者你可以使用真正的解析器,如[parsec](http://hackage.haskell.org/package/parsec)。 –
听起来这些单词是用逗号*和*引号分隔的? –
@BenMillwood词语被引号包围,并用逗号分隔。 –