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
pgpPShNY0Mieb.pgp
Description: PGP signature