haskell 如何正确删除禁用词?

cigdeys3  于 2023-02-13  发布在  其他
关注(0)|答案(2)|浏览(167)

我想删除一行中所有以符号@开头的单词,但我不完全明白如何表达,很明显,你可以这样写:
1.将字符串拆分为单词
1.使用列表过滤器剔除不必要的单词
但我猜我不懂怎么断行,因为除了空格,还有\t\n这样的字符,而且,我会丢失它们,无法恢复原文。
我想得到的一个例子:
原始字符串:

haha lala\n@delete_me all-ok

预期结果:

haha lala\nall-ok
0dxa2lsx

0dxa2lsx1#

您可能希望将Data.List.Split.splitData.List.Split.oneOf一起使用。
它返回包含分隔符的拆分单词,以便您可以使用它们重新构建文本。

split (oneOf "xyz") "aazbxyzcxd" == ["aa","z","b","x","","y","","z","c","x","d"]
hc8w905p

hc8w905p2#

另一种看待这个问题的方法是,我们希望删除以at符号@开头的非空格字符串,以及后面的任何空格,我们根本不想对换行符或其他字符进行特殊处理,这可以用一个简单的递归函数span/breakdropWhile来表示:

censor :: String -> String

censor "" = ""

censor text0 = spaces ++ nonspaces ++ censor rest
  where

    (spaces, text1) = span isSpace text0

    (word, text2) = break isSpace text1

    (nonspaces, rest)

      | banned word
      = ("", trim text2)

      | otherwise
      = (word, text2)

banned :: String -> Bool
banned ('@' : _) = True
banned _ = False

trim :: String -> String
trim = dropWhile isSpace

考虑一个例子:

  1. censor " send @beans money to sam@example.com"
    1.返回" ""send @beans…"
    1.返回"send"" @beans…"
  2. banned"send"返回false,因此我们将保留它
    1.我们递归调用censor " @beans money…"
    1.返回" ""@beans money…"
    1.返回"@beans"" money…"
    1.现在banned返回true,因此我们删除它并修整其余部分
    1.我们递归调用censor "money…"
    1.我们保留所有剩余的子字符串,包括sam@example.com,因为它不是banned
    1.最后,我们到达字符串的末尾,censor ""返回""
    最终结果为以下表达式:
"  " ++ "send" ++ " " ++ "" ++ "money" ++ " " ++ "to" ++ " " ++ "sam@example.com" ++ ""

注意,我们对输入字符串进行了一系列更新,得到了一系列变量text0text1text2rest作为中间状态,考虑一下如何使用State来表示这个模式。

相关问题