string 如何在 Haskell 中拆分字符串?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4978578/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to split a string in Haskell?
提问by Eric Wilson
Is there a standard way to split a string in Haskell?
在 Haskell 中是否有标准的方法来分割字符串?
lines
and words
work great from splitting on a space or newline, but surely there is a standard way to split on a comma?
lines
并且words
在空格或换行符上分割效果很好,但是肯定有一种标准的逗号分割方法吗?
I couldn't find it on Hoogle.
我在 Hoogle 上找不到它。
To be specific, I'm looking for something where split "," "my,comma,separated,list"
returns ["my","comma","separated","list"]
.
具体来说,我正在寻找split "," "my,comma,separated,list"
返回的东西["my","comma","separated","list"]
。
采纳答案by Jonno_FTW
There is a package for this called split.
有一个名为split的包。
cabal install split
Use it like this:
像这样使用它:
ghci> import Data.List.Split
ghci> splitOn "," "my,comma,separated,list"
["my","comma","separated","list"]
It comes with a lot of other functions for splitting on matching delimiters or having several delimiters.
它带有许多其他功能,用于分割匹配的分隔符或具有多个分隔符。
回答by Steve
Remember that you can look up the definition of Prelude functions!
请记住,您可以查找 Prelude 函数的定义!
http://www.haskell.org/onlinereport/standard-prelude.html
http://www.haskell.org/onlinereport/standard-prelude.html
Looking there, the definition of words
is,
看那里,定义words
是,
words :: String -> [String]
words s = case dropWhile Char.isSpace s of
"" -> []
s' -> w : words s''
where (w, s'') = break Char.isSpace s'
So, change it for a function that takes a predicate:
因此,将其更改为采用谓词的函数:
wordsWhen :: (Char -> Bool) -> String -> [String]
wordsWhen p s = case dropWhile p s of
"" -> []
s' -> w : wordsWhen p s''
where (w, s'') = break p s'
Then call it with whatever predicate you want!
然后用你想要的任何谓词调用它!
main = print $ wordsWhen (==',') "break,this,string,at,commas"
回答by Emmanuel Touzery
If you use Data.Text, there is splitOn:
如果使用 Data.Text,则有 splitOn:
http://hackage.haskell.org/packages/archive/text/0.11.2.0/doc/html/Data-Text.html#v:splitOn
http://hackage.haskell.org/packages/archive/text/0.11.2.0/doc/html/Data-Text.html#v:splitOn
This is built in the Haskell Platform.
这是在 Haskell 平台中构建的。
So for instance:
所以例如:
import qualified Data.Text as T
main = print $ T.splitOn (T.pack " ") (T.pack "this is a test")
or:
或者:
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.Text as T
main = print $ T.splitOn " " "this is a test"
回答by evilcandybag
回答by antimatter
Use Data.List.Split
, which uses split
:
使用Data.List.Split
,它使用split
:
[me@localhost]$ ghci
Prelude> import Data.List.Split
Prelude Data.List.Split> let l = splitOn "," "1,2,3,4"
Prelude Data.List.Split> :t l
l :: [[Char]]
Prelude Data.List.Split> l
["1","2","3","4"]
Prelude Data.List.Split> let { convert :: [String] -> [Integer]; convert = map read }
Prelude Data.List.Split> let l2 = convert l
Prelude Data.List.Split> :t l2
l2 :: [Integer]
Prelude Data.List.Split> l2
[1,2,3,4]
回答by fuz
Try this one:
试试这个:
import Data.List (unfoldr)
separateBy :: Eq a => a -> [a] -> [[a]]
separateBy chr = unfoldr sep where
sep [] = Nothing
sep l = Just . fmap (drop 1) . break (== chr) $ l
Only works for a single char, but should be easily extendable.
仅适用于单个字符,但应易于扩展。
回答by Frank Meisschaert
split :: Eq a => a -> [a] -> [[a]]
split d [] = []
split d s = x : split d (drop 1 y) where (x,y) = span (/= d) s
E.g.
例如
split ';' "a;bb;ccc;;d"
> ["a","bb","ccc","","d"]
A single trailing delimiter will be dropped:
将删除单个尾随分隔符:
split ';' "a;bb;ccc;;d;"
> ["a","bb","ccc","","d"]
回答by fp_mora
Without importing anything a straight substitution of one character for a space, the target separator for words
is a space. Something like:
在不导入任何字符的情况下直接替换一个空格,目标分隔符words
是一个空格。就像是:
words [if c == ',' then ' ' else c|c <- "my,comma,separated,list"]
or
或者
words let f ',' = ' '; f c = c in map f "my,comma,separated,list"
You can make this into a function with parameters. You can eliminate the parameter character-to-matchmy matching many, like in:
你可以把它变成一个带参数的函数。您可以消除参数character-to-match我的匹配项,例如:
[if elem c ";,.:-+@!$#?" then ' ' else c|c <-"my,comma;separated!list"]
回答by Robin Begbie
I started learning Haskell yesterday, so correct me if I'm wrong but:
我昨天开始学习 Haskell,如果我错了,请纠正我,但是:
split :: Eq a => a -> [a] -> [[a]]
split x y = func x y [[]]
where
func x [] z = reverse $ map (reverse) z
func x (y:ys) (z:zs) = if y==x then
func x ys ([]:(z:zs))
else
func x ys ((y:z):zs)
gives:
给出:
*Main> split ' ' "this is a test"
["this","is","a","test"]
or maybe you wanted
或者你想要
*Main> splitWithStr " and " "this and is and a and test"
["this","is","a","test"]
which would be:
这将是:
splitWithStr :: Eq a => [a] -> [a] -> [[a]]
splitWithStr x y = func x y [[]]
where
func x [] z = reverse $ map (reverse) z
func x (y:ys) (z:zs) = if (take (length x) (y:ys)) == x then
func x (drop (length x) (y:ys)) ([]:(z:zs))
else
func x ys ((y:z):zs)
回答by Evi1M4chine
I don't know how to add a comment onto Steve's answer, but I would like to recommend the
GHC libraries documentation,
and in there specifically the
Sublist functions in Data.List
我不知道如何在 Steve 的回答上添加评论,但我想推荐
GHC 库文档,
特别是
Data.List 中的 Sublist 函数
Which is much better as a reference, than just reading the plain Haskell report.
作为参考,这比阅读普通的 Haskell 报告要好得多。
Generically, a fold with a rule on when to create a new sublist to feed, should solve it too.
一般来说,一个关于何时创建一个新的子列表来提供规则的折叠也应该解决它。