在Haskell List Comprehensions中做一些替换

时间:2013-03-10 03:46:47

标签: string list haskell list-comprehension

我的问题是,如果我输入一个包含Hello, today is a Nice Day!!之类的字符串,我怎样才能摆脱空格和标点符号,并用小写字母替换大写字母?

我知道如何删除它们但不知道如何替换它们。

还要摆脱标点符号。

抱歉,我不知道如何乱用字符串,只有数字。

testList xs = [if x = [,|.|?|!] then " "  | x<-xs] 

6 个答案:

答案 0 :(得分:7)

import Data.Char

如果要将标点符号转换为空格,将字符从大写转换为小写:

testList xs = [if x `elem` ",.?!" then ' ' else toLower x | x<-xs]

示例:testList "TeST,LiST!" == "test list "

如果要删除标点符号并将字符从大写转换为小写:

testList2 xs = [toLower x | x<-xs, not (x `elem` ",.?!")]

示例:testList2 "Te..S,!t LiS?T" == "test list"

如果您不想或不能导入Data.Char,这是toLower的实现:

toLower' :: Char -> Char
toLower' char 
    | isNotUppercase = char -- no change required
    | otherwise = toEnum (codeChar + diffLowerUpperChar) -- char lowered
    where
      codeChar = fromEnum char -- each character has a numeric code
      code_A = 65
      code_Z = 90
      code_a = 97
      isNotUppercase = codeChar < code_A || codeChar > code_Z
      diffLowerUpperChar = code_a - code_A

答案 1 :(得分:4)

我一直没有在Haskell中编写代码很长一段时间,但是下面应该删除无效字符(用空格替换它们)并将字符从大写转换为小写:

import Data.Char

replace invalid xs = [if elem x invalid then ' ' else toLower x | x <- xs]

另一种做法:

repl invalid [] = []
repl invalid (x:xs) | elem x invalid = ' ' : repl invalid xs
                    | otherwise      = toLower x : repl invalid xs

您可以像这样调用replace(或repl)函数:

replace ",.?!" "Hello, today is a Nice Day!!"

以上代码将返回:

"hello  today is a nice day  "

编辑:我在Haskell中使用toLower中的Data.Char函数,但如果您想自己编写,请在此处查看Stack Overflow。之前已经问过这个问题。

答案 2 :(得分:4)

您可以在Data.Char中找到所需的功能:

import Data.Char

process str = [toLower c | c <- str , isAlpha c]

虽然我个人认为功能构成方法更清晰:

process = map toLower . filter isAlpha

答案 3 :(得分:2)

要摆脱标点符号,您可以使用像这样的过滤器

[x | x<-[1..10], x `mod` 2 == 0]

您使用的“if”不会过滤。将if放在列表理解的“map”部分中只会在两个选项之间进行选择,但是你无法将它们过滤掉。

至于将事物转换为小写,它的功能与你已经完成的数字相同:

[x*2 | x <- [1..10]]

答案 4 :(得分:0)

这是一个没有导入模块的版本,使用fromEnum和toEnum来选择允许的字符:

testList xs = 
  filter (\x -> elem (fromEnum x) ([97..122] ++ [32] ++ [48..57])) $ map toLower' xs 
    where toLower' x = if elem (fromEnum x) [65..90] 
                          then toEnum (fromEnum x + 32)::Char 
                          else x

OUTPUT:
*Main> testList "Hello, today is a Nice Day!!"
"hello today is a nice day"

对于无模块替换功能,这样的事情可能会起作用:

myReplace toReplace xs = map myReplace' xs where
  myReplace' x
    | elem (fromEnum x) [65..90] = toEnum (fromEnum x + 32)::Char
    | elem x toReplace           = ' '
    | otherwise                  = x

OUTPUT:
*Main> myReplace "!," "Hello, today is a Nice Day!! 123"
"hello  today is a nice day   123"

答案 5 :(得分:0)

使用适用样式

“学到一个伟大的Haskell!”一书中的文字引文:

使用列表上的应用样式通常可以很好地替代 列出理解。在第二章中,我们希望看到所有 [2,5,10]和[8,10,11]的可能乘积,所以我们这样做:

[ x*y | x <- [2,5,10], y <- [8,10,11]]         

我们只是从两个列表中绘制,并在两个列表之间应用函数 元素的每种组合。这可以在应用程序中完成 风格:

(*) <$> [2,5,10] <*> [8,10,11]

对我来说,这似乎很清楚,因为更容易看出我们只是 在两个非确定性计算之间调用*。如果我们想要全部 这两个列表的可能产品超过50,我们只是 做:

filter (>50) $ (*) <$> [2,5,10] <*> [8,10,11]
-- [55,80,100,110]

Functors, Applicative Functors and Monoids