[英]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"]
對於更難的問題,或者不太可能被丟棄的代碼,更強大的技術是有意義的。 特別是,您可以通過使用解析器組合器(例如parsec或uu-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.