6

我的问题是,如果我输入一个包含诸如Hello, today is a Nice Day!!如何摆脱空格和标点符号以及用小写字母替换大写字母的字符串?

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

还要去掉标点符号。

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

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

6 回答 6

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
于 2013-03-10T08:28:03.163 回答
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(or repl) 函数:

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

上面的代码将返回:

"hello  today is a nice day  "

编辑:我正在使用 Haskell 中的toLower函数Data.Char,但如果你想自己编写,请在 Stack Overflow 上查看。这个问题以前有人问过。

于 2013-03-10T04:16:55.367 回答
4

您将在以下位置找到您需要的功能Data.Char

import Data.Char

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

虽然就个人而言,我认为函数组合方法更清晰:

process = map toLower . filter isAlpha
于 2013-03-10T05:27:20.290 回答
2

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

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

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

至于将事物转换为小写,它与您已经可以在数字上实现的技巧相同:

[x*2 | x <- [1..10]]
于 2013-03-10T04:04:43.163 回答
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"
于 2013-03-10T04:37:37.673 回答
0

使用应用风格

来自“Learn You a Haskell for Great Good!”一书的文字引用:

在列表上使用 applicative 样式通常可以很好地替代列表推导式。在第二章中,我们想查看 [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 和 Monoids

于 2020-08-13T02:34:14.230 回答