String 如何将字符串中的空格字符替换为";%20“吗;?

String 如何将字符串中的空格字符替换为";%20“吗;?,string,haskell,list-comprehension,String,Haskell,List Comprehension,我想编写一个Haskell函数,它接受一个字符串,并用特殊代码%20替换任何空格字符。例如: sanitize "http://cs.edu/my homepage/I love spaces.html" -- "http://cs.edu/my%20homepage/I%20love%20spaces.html" 我正在考虑使用concat函数,这样我就可以将列表列表连接到一个普通列表中 changer :: [Char] -> [Char] -> [Char] changer

我想编写一个Haskell函数,它接受一个字符串,并用特殊代码%20替换任何空格字符。例如:

sanitize "http://cs.edu/my homepage/I love spaces.html"
-- "http://cs.edu/my%20homepage/I%20love%20spaces.html"
我正在考虑使用concat函数,这样我就可以将列表列表连接到一个普通列表中

changer :: [Char] -> [Char] -> [Char]
changer [] res = res
changer (x:xs) res = changer xs (res ++ (if x == ' ' then "%20" else [x]))

sanitize :: [Char] -> [Char]
sanitize xs = changer xs ""

main = print $ sanitize "http://cs.edu/my homepage/I love spaces.html"
-- "http://cs.edu/my%20homepage/I%20love%20spaces.html"
sanitize
函数的目的是调用执行实际工作的
changer
。现在,
changer
递归地调用自身,直到当前字符串耗尽

changer xs (res ++ (if x == ' ' then "%20" else [x]))
它接受第一个字符
x
,并检查它是否等于
,如果是,则给出
%20
,否则实际字符本身将作为字符串,然后将其与累积字符串连接


注意:这可能不是最佳解决方案。

您正在寻找的高阶函数是

concatMap :: (a -> [b]) -> [a] -> [b]
在您的例子中,选择
a~Char,b~Char
(注意
String
只是
[Char]
的类型同义词),我们得到

所以一旦你写了一个函数

escape :: Char -> String
escape ' ' = "%20"
escape c = [c]
你可以通过写字符串来提升它

sanitize :: String -> String
sanitize = concatMap escape

使用理解也有效,如下所示

changer :: [Char] -> [Char]
changer xs = [ c | v <- xs , c <- if (v == ' ') then "%20" else [v] ]
changer::[Char]->[Char]

changer xs=[c | v您可以使用
数据.List
模块中的
插入
功能。它使用给定的分隔符和列表进行计算,然后计算结果

sanitize = intercalate "%20" . words
或使用模式匹配:

sanitize [] = []
sanitize (x:xs) = go x    xs
          where   go ' '  []     = "%20" 
                  go y    []     = [y] 
                  go ' '  (x:xs) = '%':'2':'0': go x xs  
                  go y    (x:xs) = y: go x xs

Shanth模式匹配方法的另一个表达式:

sanitize = foldr go []
  where
    go ' ' r = '%':'2':'0':r
    go c   r = c:r

谢谢你的帮助。知道如何使用concat吗?@WaleedAldeghaither
++
是concat操作符。是的,我指的是concatfunction@WaleedAldeghaither您可以这样做
changer xs(concat[res,(如果x==”,那么“%20”else[x]))
太好了!谢谢你可能想看看concatMap。太棒了!我喜欢你的方式,它让我理解它很强,也很简单。注意:)
插入“%20”.words
不太管用,因为
words
删除前导空格和尾随空格,将连续空格修剪为单个空格,并使用
isSpace
,这比
(==“”)
更不挑剔。
sanitize = foldr go []
  where
    go ' ' r = '%':'2':'0':r
    go c   r = c:r