192 votes

Comment diviser une chaîne de caractères en Haskell ?

Existe-t-il un moyen standard de diviser une chaîne de caractères en Haskell ?

lines y words fonctionnent très bien lorsqu'ils sont séparés par un espace ou une nouvelle ligne, mais il existe sûrement un moyen standard de les séparer par une virgule ?

Je ne l'ai pas trouvé sur Hoogle.

Pour être plus précis, je cherche quelque chose où split "," "my,comma,separated,list" renvoie à ["my","comma","separated","list"] .

27 votes

J'aimerais vraiment qu'une telle fonction soit disponible dans une future version de l'application. Data.List ou même Prelude . C'est tellement commun et désagréable s'il n'est pas disponible pour le code-golf.

186voto

Steve Points 2517

N'oubliez pas que vous pouvez consulter la définition des fonctions Prelude !

http://www.haskell.org/onlinereport/standard-prelude.html

En regardant là, la définition de words est,

words   :: String -> [String]
words s =  case dropWhile Char.isSpace s of
                      "" -> []
                      s' -> w : words s''
                            where (w, s'') = break Char.isSpace s'

Donc, changez-le pour une fonction qui prend un prédicat :

wordsWhen     :: (Char -> Bool) -> String -> [String]
wordsWhen p s =  case dropWhile p s of
                      "" -> []
                      s' -> w : wordsWhen p s''
                            where (w, s'') = break p s'

Ensuite, appelez-le avec le prédicat que vous voulez !

main = print $ wordsWhen (==',') "break,this,string,at,commas"

157voto

Jonno_FTW Points 3520

Il existe un paquet pour cela appelé divisé .

cabal install split

Utilisez-le comme ça :

ghci> import Data.List.Split
ghci> splitOn "," "my,comma,separated,list"
["my","comma","separated","list"]

Il est doté de nombreuses autres fonctions permettant de diviser sur des délimiteurs correspondants ou sur plusieurs délimiteurs.

9 votes

Cool. Je n'étais pas au courant de ce paquet. C'est le site Le paquet split ultime car il donne beaucoup de contrôle sur l'opération (couper les espaces dans les résultats, laisser les séparateurs dans le résultat, enlever les séparateurs consécutifs, etc...). Il y a tellement de façons de diviser des listes, qu'il n'est pas possible d'avoir en une seule fois split qui répondra à tous les besoins, vous avez vraiment besoin de ce genre de paquet.

1 votes

Sinon, si des paquets externes sont acceptables, MissingH fournit également une fonction de fractionnement : hackage.haskell.org/packages/archive/MissingH/1.2.0.0/doc/html/ Ce paquet fournit également beaucoup d'autres fonctions "agréables à avoir" et je trouve que pas mal de paquets en dépendent.

46 votes

Le paquet split fait maintenant partie de la plateforme haskell depuis la dernière version.

41voto

Emmanuel Touzery Points 1677

Si vous utilisez Data.Text, il y a splitOn :

http://hackage.haskell.org/packages/archive/text/0.11.2.0/doc/html/Data-Text.html#v:splitOn

Il est construit dans la plateforme Haskell.

Ainsi, par exemple :

import qualified Data.Text as T
main = print $ T.splitOn (T.pack " ") (T.pack "this is a test")

ou :

{-# LANGUAGE OverloadedStrings #-}

import qualified Data.Text as T
main = print $ T.splitOn " " "this is a test"

2 votes

@RussAbbott probablement vous avez besoin d'une dépendance à la text ou l'installer. Mais cela aurait sa place dans une autre question.

2 votes

Impossible de faire correspondre le type 'T.Text' avec 'Char' Type attendu : [Char] Type réel : [T.Texte]

19voto

evilcandybag Points 1163

Dans le module Text.Regex (qui fait partie de la plate-forme Haskell), il existe une fonction :

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

qui divise une chaîne de caractères en fonction d'une expression régulière. L'API se trouve à l'adresse suivante Hackage .

2 votes

Could not find module ‘Text.Regex’ Perhaps you meant Text.Read (from base-4.10.1.0)

14voto

FUZxxl Points 21462

Essaie celle-là :

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

Ne fonctionne que pour un seul personnage, mais devrait être facilement extensible.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X