如何从字符串中删除单词列表

6

我希望在Clojure中实现以下功能:

例如,我有一个需要删除的单词向量:

(def forbidden-words [":)" "the" "." "," " " ...many more...])

...以及一个字符串向量:

(def strings ["the movie list" "this.is.a.string" "haha :)" ...many more...])

因此,每个字符串中都应该删除每个禁止词,结果将是:["movie list" "thisisastring" "haha"]。
如何实现这一点?

这个链接对你有帮助吗:http://github.com/richhickey/clojure-contrib/blob/bacf49256673242bb7ce09b9f5983c27163e5bfc/src/main/clojure/clojure/contrib/string.clj#L162 - ilija veselica
3个回答

7
(def forbidden-words [":)" "the" "." ","])
(def strings ["the movie list" "this.is.a.string" "haha :)"])
(let [pattern (->> forbidden-words (map #(java.util.regex.Pattern/quote %)) 
                (interpose \|)  (apply str))]
  (map #(.replaceAll % pattern "") strings))

我更喜欢这个,因为它只对输入字符串进行一次遍历。 - Stuart Sierra
关于您下面的评论,您是否尝试使用 ["th:)e"] 测试了自己的答案?当我尝试时,它无法正常工作。 - A. Levy
@ALevy 对我而言,它的工作表现如预期:对于 ["th:)e" ":the)"],它输出 ("the" ":)"),仅移除出现在输入字符串中的禁用单词 - 而不是在删除其他禁用单词后出现的禁止单词。我的解决方案是唯一一个返回值不依赖于禁用单词向量排序的解决方案。 - cgrand
我最喜欢这个解决方案,因为它不使用循环并且速度快。 - Zeljko

1
(use 'clojure.contrib.str-utils)
(import 'java.util.regex.Pattern)
(def forbidden-words [":)" "the" "." "," " "])
(def strings ["the movie list" "this.is.a.string" "haha :)"])
(def regexes (map #(Pattern/compile % Pattern/LITERAL) forbidden-words))
(for [s strings] (reduce #(re-gsub %2 "" %1) s regexes))

+1,因为这个有效。对于那些想要在最前沿测试的人,请注意,在当前源中,clojure.contrib.str-utils已更名为clojure.contrib.string,而re-gsub已变为replace-re。还要注意,如果从两个其他单词之间删除一个单词应该意味着删除恰好一个围绕它的空格(而不是像上面的代码一样没有),并且字符串的开头和结尾的单词应正确处理,则需要进行更复杂的正则表达式操作。 - Michał Marczyk
你可以用re-pattern替换Pattern/compile的调用。 - Brian Carper
@Brian:re-pattern不接受必要的Pattern/LITERAL参数。 - Michał Marczyk
1
所有的多次答案都是错误的,请使用输入["th:)e"]尝试您的解决方案。 - cgrand

0

使用函数组合和 -> 宏可以使代码变得简洁明了:

(for [s strings] 
  (-> s ((apply comp 
           (for [s forbidden-words] #(.replace %1 s ""))))))

如果你想更加“地道”,你可以使用 clojure.contrib.string 中的 replace-str,而不是 #(.replace %1 s "")

这里不需要使用正则表达式。


1
所有的多次答案都是有缺陷的: (def forbidden-words [":)" "the" "." ","]) (for [s [":the)"]] (-> s ((apply comp (for [s forbidden-words] #(.replace %1 s "")))))) ;; 这将返回("") - cgrand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接