1

I have this:

(defn page1 []
  (layout/render
   "index.html" 
   ({:articles (db/get-articles)})))

The function

db/get-articles

returns a list of objects which have the key body. I need to parse the body of the articles and replace, if exists, a substring "aaa12aaa" with "bbb13bbb", "aaa22aaa" with "bbb23bbb" and so on in the bodies. How can I do that so it also won't consume plenty of RAM? Is using regex effective?

UPDATE:

The pattern I need to replace is : "[something="X" something else/]". where X is a number and it's unknown. I need to change X. There can be many such patterns to replace or none.

4

3 回答 3

3

I would just use Java's String.replace or String.replaceAll or clojure.string functions: replace/replace-first.

I wouldn't waste time for premature optimisations and first measure if the simple solution works. I am not sure how big the article contents are but I guess it shouldn't be an issue.

If it turns out you really need to optimise then maybe you should switch to streaming the contents of your articles from your data storage and either implement replace manually or using a library like streamflyer to perform modifications on the fly before sending the article contents to the HTTP response stream.

于 2016-05-31T07:03:43.483 回答
1

Something like this should be plenty fast:

(mapv
  (fn [{:keys [body] :as m}]
    (assoc m :body
             (reduce-kv
               (fn [body re repl]
                 (string/replace body re repl))
               body
               {"aaa12aaa" "bbb13bbb",
                "aaa22aaa" "bbb23bbb"})))
  [{:body "xy aaa12aaa fo aaa22aaa"}])

If you can guarantee that the string only occurs once you can replace replace by replace-first.

于 2016-05-31T08:23:43.877 回答
-1

Regex works great in clojure:

(ns clj.core
  (:use tupelo.core)
  (:require
    [clojure.string :as str]
    )

(spyx (str/replace "xyz-aaa12aaa-def" #"aaa12aaa" "bbb13bbb"))

;=>  (str/replace "xyz-aaa12aaa-def" #"aaa12aaa" "bbb13bbb") => "xyz-bbb13bbb-def"
于 2016-05-31T06:53:07.250 回答