[英]Cutting a string into a list in Haskell?
是否可以剪断一根绳子,例如
"one , Two"
到一个列表
["one", "two"]
要不就
"one", "two"
谢谢
有一个完整的函数模块用于不同的策略来拆分列表(例如字符串,它只是一个字符列表): Data.List.Split
使用这个,你可以做
import Data.List.Split
> splitOn " , " "one , Two"
["one","Two"]
常规的旧列表操作在这里就足够了,
import Data.Char
> [ w | w <- words "one , Two", all isAlpha w ]
["one","Two"]
又名
> filter (all isAlpha) . words $ "one , Two"
["one","Two"]
列表黑客、解析和设计
文本处理有一定的权力和权重。 在最简单的情况下,基于列表的解决方案,例如上面的解决方案,提供非常少的句法噪音,以获得快速的结果(与 shell 脚本中的快速'n'dirty 文本处理相同)。
列表操作可能会变得非常复杂,您可能会考虑,例如通用拆分库,用于在任意文本上拆分列表,
> splitOn " , " "one , Two"
["one","Two"]
对于更难的问题,或者不太可能被丢弃的代码,更强大的技术是有意义的。 特别是,您可以通过使用解析器组合器(例如parsec或uu-parsinglib )将问题描述为语法来避免脆弱的模式匹配。 随着时间的推移,通过解析器描述的字符串处理往往会导致代码更加健壮,因为随着需求的变化,修改以组合器样式编写的解析器相对容易。
关于正则表达式的注意事项:列表匹配和正则表达式在易用性和(不)安全性方面大致相同,因此出于本讨论的目的,您可以将“正则表达式”替换为“列表拆分”。 如果代码打算长期存在,解析几乎总是正确的方法。
如果您不想安装拆分 package ( 请参阅 Frerich Raabe 的回答),这里是splitOn
function 的实现,它对依赖关系很清楚:
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
未经测试,使用 Parsec。 也可能有一个正则表达式分隔符。
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
会很好,类似于我如何使用liftM2
设法折叠elements
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.