我想删除一行中所有以符号@开头的单词,但我不完全明白如何表达,很明显,你可以这样写:1.将字符串拆分为单词1.使用列表过滤器剔除不必要的单词但我猜我不懂怎么断行,因为除了空格,还有\t和\n这样的字符,而且,我会丢失它们,无法恢复原文。我想得到的一个例子:原始字符串:
@
\t
\n
haha lala\n@delete_me all-ok
预期结果:
haha lala\nall-ok
0dxa2lsx1#
您可能希望将Data.List.Split.split与Data.List.Split.oneOf一起使用。它返回包含分隔符的拆分单词,以便您可以使用它们重新构建文本。
Data.List.Split.split
Data.List.Split.oneOf
split (oneOf "xyz") "aazbxyzcxd" == ["aa","z","b","x","","y","","z","c","x","d"]
hc8w905p2#
另一种看待这个问题的方法是,我们希望删除以at符号@开头的非空格字符串,以及后面的任何空格,我们根本不想对换行符或其他字符进行特殊处理,这可以用一个简单的递归函数span/break和dropWhile来表示:
span
break
dropWhile
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
考虑一个例子:
censor " send @beans money to sam@example.com"
" "
"send @beans…"
"send"
" @beans…"
banned
censor " @beans money…"
"@beans money…"
"@beans"
" money…"
censor "money…"
sam@example.com
censor ""
""
" " ++ "send" ++ " " ++ "" ++ "money" ++ " " ++ "to" ++ " " ++ "sam@example.com" ++ ""
注意,我们对输入字符串进行了一系列更新,得到了一系列变量text0、text1、text2、rest作为中间状态,考虑一下如何使用State来表示这个模式。
text0
text1
text2
rest
State
2条答案
按热度按时间0dxa2lsx1#
您可能希望将
Data.List.Split.split
与Data.List.Split.oneOf
一起使用。它返回包含分隔符的拆分单词,以便您可以使用它们重新构建文本。
hc8w905p2#
另一种看待这个问题的方法是,我们希望删除以at符号
@
开头的非空格字符串,以及后面的任何空格,我们根本不想对换行符或其他字符进行特殊处理,这可以用一个简单的递归函数span
/break
和dropWhile
来表示:考虑一个例子:
censor " send @beans money to sam@example.com"
1.返回
" "
和"send @beans…"
1.返回
"send"
和" @beans…"
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 ""
返回""
最终结果为以下表达式:
注意,我们对输入字符串进行了一系列更新,得到了一系列变量
text0
、text1
、text2
、rest
作为中间状态,考虑一下如何使用State
来表示这个模式。