我有句“中国北京上海美国澳大利亚”和一组单词#{“USA”“australia”}
现在我正在编写一个函数,它将输入作为句子和一组单词,并从句子中删除:
(defn remove-words-from-sentence [sentence words]
(for [w words] (-> sentence
(.replaceAll w "")))
注意:我希望替换确切的单词出现..所以如果单词包含字母“a”,那么所有的a都不应该被替换为句子,只有单词a应该被替换。
但是上面的功能不起作用,有什么帮助?
答案 0 :(得分:0)
for
迭代给定的seq,产生另一个序列。因此,您要生成一个列表,其中的元素分别代表每个替换,但不会合并。
你想要的是先替换第一个单词,然后 - 在替换的结果上 - 删除第二个单词,依此类推。这是reduce
的典型案例:
(defn remove-words-from-sentence
[sentence words]
(reduce #(.replace % %2 "") sentence words))
(请注意,replace
与replaceAll
的作用相同,但使用文字替换,不允许使用正则表达式。)
编辑:这只是修复了OP尝试做的事情。它可能会产生不需要的结果,例如其中一个词是" eij" (因为它将删除那部分"北京")。解决这个问题的一种方法是使用(.replaceAll % (str "\\b\\Q" %2 "\\E\\b\\s*") "")
进行替换;然后trim
结果。因此,更可靠的版本可能如下所示:
(require '[clojure.string :as string])
(defn remove-words-from-sentence
[sentence words]
(let [pattern (->> (for [w words] (str "\\b\\Q" w "\\E\\b"))
(string/join "|")
(format "(%s)\\s*"))]
(.trim (.replaceAll sentence pattern ""))))
但这一切都取决于OP想要的东西。
答案 1 :(得分:0)
你能做到的一种方法是将句子分成单个单词,并在一个集合中删除单词,并过滤出句子中的单词。
(let [sentence (clojure.string/split (read-line) #" ")
words (set (clojure.string/split (read-line) #" "))]
(clojure.string/join " "
(filter (complement words)
sentence)))
user=> china beijing shanghai USA australia ;;input sentence
user=> china USA ;;input words
user=> "beijing shanghai australia" ;;output
编辑:
Thumbnail提请我注意(filter (complement pred) coll)
相当于(remove pred coll)
。您可以通过查看remove
(source remove)
(defn remove
"Returns a lazy sequence of the items in coll for which
(pred item) returns false. pred must be free of side-effects."
{:added "1.0"
:static true}
[pred coll]
(filter (complement pred) coll))
nil
所以可以使用remove
代替
(let [sentence (clojure.string/split (read-line) #" ")
words (set (clojure.string/split (read-line) #" "))]
(clojure.string/join " " (remove words sentence)))
这种方式更具可读性。您可以将其读作"从句子中删除单词"。
答案 2 :(得分:0)
user> (defn remove-words-from-sentence
[sentence & words]
(loop [sentence sentence
ws words]
(if-not (seq ws)
sentence
(recur
(clojure.string/replace sentence (first ws) "")
(rest ws)))))
#'user/remove-words-from-sentence
user> (remove-words-from-sentence "Hello, World" "World")
;=> "Hello, "
user> (remove-words-from-sentence "Hello, World" "ll" "o" "H")
;=> "e, Wrld"
答案 3 :(得分:0)
到目前为止,答案并未处理指定输入类型(字符串和集合)的问题
由于输入的单词在问题中被指定为一个集合,而句子是一个字符串 - 最简单的解决方案可能是使用集合 - 也很容易理解;
(defn remove-words-from-sentence [sentence words]
(str/join " "(set/difference (into #{} (str/split sentence #" ")) words))
)
按宣传方式工作:
(remove-words-from-sentence "china beijing shanghai USA australia" #{"USA" "australia"})
"beijing china shanghai"