解析我很新的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詞語被引號包圍,並用逗號分隔。 –