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
