2011-11-25 37 views
9

我需要在Haskell中的字符串標記器,但有顯然什麼都沒有在Prelude或其他模塊中定義。在Data.Text中有splitOn,但是使用起來很麻煩,因爲你需要將String包裝爲Text。Haskell字符串標記器函數

令牌化器不是很難做,所以我寫了一個(它不處理多個相鄰的分隔符,但它對我所需要的很有效)。我覺得這樣的事情應該是已經在某處模塊..

這是我

tokenizer :: Char -> String -> [String] 
tokenizer delim str = tokHelper delim str [] 

tokHelper :: Char -> String -> [String] -> [String] 
tokHelper d s acc 
    | null pos = reverse (pre:acc) 
    | otherwise = tokenizer d (tail pos) (pre:acc) 
     where (pre, pos) = span (/=d) s 

版本我尋找更多的解決方案,互聯網和發現了一些討論,比如this blog post

最後的評論(由Mahee於2011年6月10日發佈)特別有趣。爲什麼不使用更通用的單詞來處理這個問題?我試圖尋找這樣的功能,但沒有發現..

是否有一個更簡單的方法來這或「標記」一個字符串不是一個非常反覆的問題? :)

+0

我不是一個Haskell程序員,所以拿這個機智一粒鹽。但是,我認爲你所描述的情況可能被認爲是足夠簡單的實現,即使它比「單詞」更復雜。大部分其他解析任務超出「單詞」級別,可能會足夠複雜,而不是像解析器組合器(例如parsec)那樣值得做。 – Gian

+2

我實際上推薦幾乎所有的代碼,你使用文本而不是字符串。這是一個性能更好的圖書館。如果您對此聲明有更多疑問,我會通過電子郵件發送給咖啡館。 –

+0

你對此絕對正確:)謝謝。我剛纔在使用惰性IO時遇到了一些問題(嘗試了幾個小時才使它與getContents和getLine一起工作,在網上閱讀等)。但是在文本上使用相同的功能,我的問題立即得到解決。我不知道如果我使用文本,性能會變差,但最終我的應用程序沒有明顯的差異。我將不得不研究文本如何更詳細地工作:) – Adi

回答

15

split library是你所需要的。使用cabal install split進行安裝,然後您可以訪問大量分割/標記器樣式函數。

從庫中的一些例子:

> import Data.List.Split 
> splitOn "x" "axbxc" 
["a","b","c"] 
> splitOn "x" "axbxcx" 
["a","b","c",""] 
> endBy ";" "foo;bar;baz;" 
["foo","bar","baz"] 
> splitWhen (<0) [1,3,-4,5,7,-9,0,2] 
[[1,3],[5,7],[0,2]] 
> splitOneOf ";.," "foo,bar;baz.glurk" 
["foo","bar","baz","glurk"] 
> splitEvery 3 ['a'..'z'] 
["abc","def","ghi","jkl","mno","pqr","stu","vwx","yz"] 

來自同一個庫中的wordsBy功能是words仿製像你想:

wordsBy (=='x') "dogxxxcatxbirdxx" == ["dog","cat","bird"] 
+0

謝謝,這正是我所需要的 – Adi