2010-03-31 20 views
6

Lo que me gustaría hacer (en Clojure):Cómo quitar lista de palabras a partir de cadenas

Por ejemplo, tengo un vector de palabras que necesitan ser removidos:

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

.. . y un vector de cadenas:

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

Así, cada palabra prohibida debe ser removido de cada cuerda, y el resultado, en este caso, sería la siguiente: [ "lista de la película" "thisisastring" "jaja"].

¿Cómo hacer esto?

+0

Será este enlace de ayuda que: http://github.com/richhickey/clojure-contrib/blob/bacf49256673242bb7ce09b9f5983c27163e5bfc/src/main/clojure/clojure/contrib/string.clj#L162 –

Respuesta

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

Me gusta más porque solo hace una pasada sobre la cadena de entrada. –

+0

Con respecto a su comentario a continuación, ¿ha probado su propia respuesta con ["th:) e"]? No funciona correctamente cuando lo intento. –

+0

@ALevy Para mí, él trabaja como se esperaba: para ["th:) e" ": the)"] produce ("the" ":)") eliminando solo las palabras prohibidas que aparecen en la cadena de entrada - y palabras no prohibidas que aparecen cuando ya has eliminado otras palabras prohibidas. Mi solución es la única cuyos valores de retorno no dependen del orden del vector de palabras prohibidas. – 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, ya esto funciona. Para aquellos a los que les gustaría probar esto en el borde de la sangría, tenga en cuenta que 'clojure.contrib.str-utils' ha sido renombrado a' clojure.contrib.string' en las fuentes actuales y 're-gsub' se ha convertido en' replace-re'. También tenga en cuenta que si eliminar una palabra de entre otras dos palabras implica eliminar exactamente uno de los espacios que lo rodean (en lugar de ninguno, como con el código anterior) * y * las palabras al principio y al final de la cadena deben manejarse correctamente , entonces se necesitaría algo más de magia regex. –

+0

Su llamada a 'Pattern/compile' se puede reemplazar por' re-pattern'. –

+0

@Brian: 're-pattern' no acepta el argumento' Pattern/LITERAL' que es necesario aquí. –

0

El uso de la composición de funciones y la macro -> esto puede ser agradable y simple:

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

Si quiere ser más 'idiomática', puede utilizar replace-str de clojure.contrib.string, en vez de #(.replace %1 s "").

No necesita usar expresiones regulares aquí.

+1

Todas las respuestas de multipaso están inherentemente rotas: (def prohibió-palabras [":)" "el" "." ","]) (para [s [": the)"]] (-> s ((aplique comp (para [s prohibidas] # (. Replace% 1 s "")))))) ;; esto devuelve ("") – cgrand

Cuestiones relacionadas