2010-03-31 39 views
6

Những gì tôi muốn làm (trong Clojure):Làm thế nào để loại bỏ danh sách các từ từ chuỗi

Ví dụ, tôi có một vector của từ mà cần phải được loại bỏ:

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

.. . và một vector của chuỗi:

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

Vì vậy, mỗi từ cấm nên được gỡ bỏ từ mỗi chuỗi, và kết quả, trong trường hợp này, sẽ là: [ "danh sách phim" "thisisastring" "haha"].

Cách thực hiện việc này?

+0

Will liên kết này giúp bạn: http://github.com/richhickey/clojure-contrib/blob/bacf49256673242bb7ce09b9f5983c27163e5bfc/src/main/clojure/clojure/contrib/string.clj#L162 –

Trả lời

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)) 
+0

Tôi thích điều này tốt hơn bởi vì nó chỉ thực hiện một lần truyền qua chuỗi đầu vào. –

+0

Về bình luận của bạn dưới đây, bạn đã thử câu trả lời của riêng mình với ["th:) e"] chưa? Nó không hoạt động chính xác khi tôi thử nó. –

+0

@ALevy Với tôi, anh ấy làm việc như mong đợi: cho ["th:) e" ":)"] nó xuất ra ("the" ":)") chỉ xóa những từ bị cấm xuất hiện trong chuỗi đầu vào - và không bị cấm các từ xuất hiện khi bạn đã loại bỏ các từ cấm. Giải pháp của tôi là giải pháp duy nhất có giá trị trả lại không phụ thuộc vào thứ tự của vectơ từ bị cấm. – cgrand

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)) 
+0

+1, kể từ những công việc này. Đối với những người muốn thử nghiệm điều này với trên cạnh chảy máu, lưu ý rằng 'clojure.contrib.str-utils' đã được đổi tên thành' clojure.contrib.string' trong các nguồn hiện tại và 're-gsub' đã trở thành' thay thế re'. Cũng lưu ý rằng nếu loại bỏ một từ giữa hai từ khác nên loại bỏ chính xác một trong các khoảng trống xung quanh nó (chứ không phải là không có, như với mã ở trên) * và * từ ở đầu và cuối của chuỗi đã được xử lý một cách chính xác , sau đó có liên quan đến ma thuật regex nhiều hơn một chút. –

+0

Bạn có thể thay thế cuộc gọi của bạn thành 'Pattern/compile' bằng' re-pattern'. –

+0

@Brian: 're-pattern' không chấp nhận đối số' Mẫu/LITERAL' cần thiết ở đây. –

0

Sử dụng hàm hợp và -> macro này có thể được tốt đẹp và đơn giản:

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

Nếu bạn muốn có nhiều 'thành ngữ', bạn có thể sử dụng replace-str từ clojure.contrib.string, thay vì của #(.replace %1 s "").

Không cần sử dụng regex ở đây.

+1

Tất cả các câu trả lời đa phần vốn đã bị hỏng: (def -bidden-words [":)" "the" "." ","]) (đối với [s [": the)"]] (-> s ((áp dụng comp (đối với các từ cấm] # (. Thay thế% 1 s ""))))))) ;; điều này trả về ("") – cgrand

Các vấn đề liên quan