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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 00:59:27  来源:igfitidea点击:

How to split a string in Haskell?

stringhaskell

提问by Eric Wilson

Is there a standard way to split a string in Haskell?

在 Haskell 中是否有标准的方法来分割字符串?

linesand wordswork 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 wordsis,

看那里,定义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

In the module Text.Regex (part of the Haskell Platform), there is a function:

在 Text.Regex 模块(Haskell 平台的一部分)中,有一个函数:

splitRegex :: Regex -> String -> [String]

which splits a string based on a regular expression. The API can be found at Hackage.

它根据正则表达式拆分字符串。API 可以在Hackage找到。

回答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 wordsis 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.

一般来说,一个关于何时创建一个新的子列表来提供规则的折叠也应该解决它。