繁体   English   中英

将字符串切割成 Haskell 中的列表?

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

对于更难的问题,或者不太可能被丢弃的代码,更强大的技术是有意义的。 特别是,您可以通过使用解析器组合器(例如parsecuu-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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM