2011-05-03 50 views

回答

0

未經檢驗的,用秒差距。 Theres可能也是一個正則表達式分隔符。

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

2

普通的舊列表操作就足夠了這裏,

import Data.Char 

> [ w | w <- words "one , Two", all isAlpha w ] 
["one","Two"] 

又名

> filter (all isAlpha) . words $ "one , Two" 
["one","Two"] 

名單黑客,分析和設計

有力量和體重的比例在文字處理中。最簡單的,基於列表的解決方案,比如上面的解決方案,提供非常小的語法噪聲,以獲得快速結果(與shell腳本中的快速文本處理相同)。

列表操作可能會相當複雜,您可能會考慮廣義split庫,用於對任意文本分割清單,

> splitOn " , " "one , Two" 
["one","Two"] 

對於較硬的問題,或代碼,不容易被扔掉,更強大的技術意義。特別是,您可以通過解析器組合器將問題描述爲語法來避免脆弱的模式匹配,例如parsecuu-parsinglib。通過解析器描述的字符串處理往往會導致隨着時間的推移更強大的代碼,因爲隨着需求的變化,修改以combinator樣式編寫的解析器相對容易。

有關正則表達式的注意事項:列表匹配和正則表達式在易用性和(非)安全性方面大致相當,因此就本討論而言,可以用「正則表達式」替換「列表拆分」。如果代碼的使用壽命很長,解析幾乎總是正確的方法。

+0

+1,但是......「one |,Two」 - > [「one |」,「Two」]'? (例如,不要使用非分隔符) – 2011-05-03 19:49:54

+0

問題不明確。 – 2011-05-03 19:52:06

+0

當然:-)但是,如果有一個解決方案涵蓋了我的測試案例, Haskell中是否存在慣用的「string.split」等價物? (或者通過動態序列匹配對任何列表進行更一般的分割)。 – 2011-05-03 19:55:01

7

有功能不同的策略來分割列表(如字符串,這僅僅是一個字符的列表)整體模塊:Data.List.Split

利用這一點,你可以做

import Data.List.Split 

> splitOn " , " "one , Two" 
["one","Two"] 
+0

由於某種原因,我沒有那個進口 – Tom 2011-05-03 20:06:12

+0

所以從Hackage中獲得它。 http://hackage.haskell.org/package/split-0.1.4 – 2011-05-03 20:08:16

+0

@Tom:Haskell平臺默認不安裝它。但是,您可以使用'cabal install split'安裝它。 – 2011-05-03 20:09:40

2

如果你不想安裝split packagesee Frerich Raabe's answer),這裏的splitOn功能的實現,對依賴重量輕:

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