在Haskell中将字符串切割成一个列表?

时间:2011-05-03 19:28:50

标签: string list haskell

是否可以剪切字符串,例如

"one , Two"

到列表

["one", "two"]

或只是

"one", "two"

感谢

4 个答案:

答案 0 :(得分:7)

有一个完整的函数模块可用于拆分列表的不同策略(例如字符串,它只是一个字符列表):Data.List.Split

使用它,你可以做到

import Data.List.Split

> splitOn " , " "one , Two"
["one","Two"]

答案 1 :(得分:2)

这里有常规的旧列表操作,

import Data.Char

> [ w | w <- words "one , Two", all isAlpha w ]
["one","Two"]

又名

> filter (all isAlpha) . words $ "one , Two"
["one","Two"]

列出黑客攻击,解析和设计

文本处理中存在功率和重量的比例。在最简单的,基于列表的解决方案(例如上面的解决方案)中,提供非常少的语法噪声,以获得快速结果(与shell脚本中的quick'n'dirty文本处理相同)。

列表操作可能变得非常复杂,您可以考虑,例如广义split库,用于拆分任意文本列表,

> splitOn " , " "one , Two"
["one","Two"]

对于更难的问题,或者对于不太可能丢弃的代码,更有力的技术是有意义的。特别是,通过使用解析器组合器(例如parsecuu-parsinglib)将问题描述为语法,可以避免脆弱的模式匹配。通过解析器描述的字符串处理往往会随着时间推移产生更强大的代码,因为随着需求的变化,修改以组合方式编写的解析器相对容易。

关于正则表达式的注意事项:列表匹配和正则表达式在易用性和(非)安全性方面大致相同,因此为了本讨论的目的,您可以将“regex”替换为“list splitting”。如果代码是长期存在的话,解析几乎总是正确的方法。

答案 2 :(得分:2)

如果你不想安装split packagesee Frerich Raabe's answer),这里是splitOn函数的一个实现,可以解释依赖关系:

import Data.List

splitOn :: Eq a => [a] -> [a] -> [[a]]
splitOn []    _  = error "splitOn: empty delimiter"
splitOn delim xs = loop xs
    where loop [] = [[]]
          loop xs | delim `isPrefixOf` xs = [] : splitOn delim (drop len xs)
          loop (x:xs) = let (y:ys) = splitOn delim xs
                         in (x:y) : ys
          len = length delim

答案 3 :(得分:0)

未经测试,使用Parsec。 Theres可能也是一个正则表达式分隔符。

firstElement :: Parser String
firstElement = many $ noneOf ' '

otherElement :: Parser String
otherElement = do many $ char ' '
                  char ','
                  many $ char ' '
                  firstElement

elements :: Parser [String]
elements = liftM2 (:) firstElement (many otherElement)

parseElements :: String -> [String]
parseElements = parse elements "(unknown)"

以某种方式清理otherElement会很不错,类似于我使用elements设法折叠liftM2的方法。