簡體   English   中英

將字符串切割成 Haskell 中的列表?

[英]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"]

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM