在Haskell中,如何从字符串的开头和结尾删除空格?

65
如何从字符串的开头和结尾删除空格?
trim "  abc " 

=>

"abc"

编辑:

好的,让我再明确一下。我不知道字符串字面量和字符串被处理得如此不同。

我想要做到这一点:

import qualified Data.Text as T
let s :: String = "  abc  "
in T.strip s

在Haskell中是否可以实现这个功能?我正在使用-XOverloadedStrings,但它似乎只适用于字面量。
13个回答

0

我对运行时或效率一无所知,但这个怎么样:

-- entirely input is to be trimmed
trim :: String -> String
trim = Prelude.filter (not . isSpace')

-- just the left and the right side of the input is to be trimmed
lrtrim :: String -> String
lrtrim = \xs -> rtrim $ ltrim xs
  where
    ltrim = dropWhile (isSpace')
    rtrim xs
      | Prelude.null xs = []
      | otherwise = if isSpace' $ last xs
                    then rtrim $ init xs
                    else xs 

-- returns True if input equals ' '
isSpace' :: Char -> Bool
isSpace' = \c -> (c == ' ')

使用Prelude以外的任何模块或库的解决方案。

一些测试:

>lrtrim ""
>""

>lrtrim "       "
>""

>lrtrim "haskell       "
>"haskell"

>lrtrim "      haskell       "
>"haskell"

>lrtrim "     h  a  s k e   ll       "
>"h  a  s k e   ll"

它可能是运行时O(n)。

但实际上我不知道,因为我不知道函数last和init的运行时间。;)


两者都是O(n),尽管init至少比last多一个因素,因为它复制了n-1个元素。对于这种情况,请使用Data.Text。使用Prelude函数自己创建可能很容易、有趣,但速度较慢。 - nomen

0

沿用其他人建议的思路,您可以通过使用以下方法避免反转字符串:

import Data.Char (isSpace)

dropFromTailWhile _ [] = []
dropFromTailWhile p item
  | p (last items) = dropFromTailWhile p $ init items
  | otherwise      = items

trim :: String -> String
trim = dropFromTailWhile isSpace . dropWhile isSpace

-3

另一种(标准)解决方案

import System.Environment
import Data.Text

strip :: String -> IO String
strip = return . unpack . Data.Text.strip . pack

main = getLine >>= Main.strip >>= putStrLn

13
为什么你会自愿用 IO 包装你的结果? - Erik Kaplun
4
不必要地将结果封装在一个单子中会树立不好的榜样,不要这样做。 - Nelo Mitranim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接