Haskell字符串标记化函数

时间:2011-11-25 04:14:09

标签: haskell functional-programming ghc haskell-platform

我在Haskell中需要一个String tokenizer,但是在Prelude或其他模块中已经定义了 。 Data.Text中有splitOn,但这很难用,因为你需要将String包装成Text。

标记化器不是很难做到这一点我写了一个(它不处理多个相邻的分隔符,但它适用于我需要它)。我觉得这样的事情应该已经存在于模块中了。

这是我的版本

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日发布)特别有趣。为什么不使一个版本的单词功能更通用来处理这个?我试着搜索这样的功能,但没找到..

是否有一种更简单的方法或者'标记'字符串而不是一个反复出现的问题? :)

2 个答案:

答案 0 :(得分:16)

split library就是您所需要的。使用cabal install split安装,然后您可以访问许多split / tokenizer样式函数。

图书馆的一些例子:

 > 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"]

答案 1 :(得分:4)

如果您要解析类似Haskell的语言,可以使用前奏中的lex函数:http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:lex