On Mon Mar 14 13:02 2011, shuaybi2 shuaybi2 wrote:
> I have a string such as:
> 
> "select * from account where acctId = _ACCT-ID_ and acctTyp = _ACCT-TYP_"
> 
> I have a map such as:
> 
> {:_ACCT-ID_ 9876 :_ACCT-TYP "B"}
> 
> I want to write a clojure function that will take the string and map as a
> parameter and return me the string with all values from the map substituted.
> 
> Output:
> 
> select * from account where acctId = 9876 and acctTyp = 'B'
> 
> Thanks for your help.

Something like the following does the trick:

(defn substitute-mappings
  [string mappings]
  (let [substitute-mapping 
        (fn [string mapping] 
          (let [pattern (java.util.regex.Pattern/quote (name (key mapping)))
                pattern (re-pattern pattern)
                matcher (re-matcher pattern string) 
                replacement (java.util.regex.Matcher/quoteReplacement (str (val 
mapping)))]
            (.replaceAll matcher replacement)))]
    (reduce substitute-mapping string (seq mappings))))

It uses reduce with an local function so that the string gets its
replacements one at a time.  Actually doing the replacement uses Java's
regular expressions.

Just a few notes about the above:

1. quote and quoteReplacement to take care of any special characters
   that may otherwise muck up replacement process
2. The name function is used to convert a keyword to a string without
   the initial colon.
3. For integers and the like, I use the str function to coerce them into
   a string that can be used as a replacement pattern.   So, you'd want
   to make sure this works correctly with any data types you want to
   use.

Sincerely,

Daniel Solano Gómez

Attachment: pgpPShNY0Mieb.pgp
Description: PGP signature

Reply via email to