diff options
author | Chouser <chouser@n01se.net> | 2009-01-04 03:44:47 +0000 |
---|---|---|
committer | Chouser <chouser@n01se.net> | 2009-01-04 03:44:47 +0000 |
commit | 66b47eebd17ddd1caa3601eb1af829e6fdb128df (patch) | |
tree | da12b8bf0a607b717bc132448031583590387ff0 | |
parent | 6b776578e93b8fa694a6126fc9ece4b150821ed4 (diff) |
re-sub and re-gsub now accept replacement fns. Patch from Juergen Gmeiner.
-rw-r--r-- | src/clojure/contrib/str_utils.clj | 34 | ||||
-rw-r--r-- | src/clojure/contrib/test_contrib/str_utils.clj | 33 |
2 files changed, 61 insertions, 6 deletions
diff --git a/src/clojure/contrib/str_utils.clj b/src/clojure/contrib/str_utils.clj index f6a59002..74a5266e 100644 --- a/src/clojure/contrib/str_utils.clj +++ b/src/clojure/contrib/str_utils.clj @@ -43,17 +43,39 @@ (list (.subSequence string prevend (.length string)))))) 0))) -(defn re-gsub +(defn re-gsub "Replaces all instances of 'pattern' in 'string' with - 'replacement'. Like Ruby's 'String#gsub'." - [#^Pattern regex replacement #^String string] - (.. regex (matcher string) (replaceAll replacement))) + 'replacement'. Like Ruby's 'String#gsub'. + + If (ifn? replacment) is true, the replacement is called with the + match. + " + [#^java.util.regex.Pattern regex replacement #^String string] + (if (ifn? replacement) + (let [parts (vec (re-partition regex string))] + (apply str + (reduce (fn [parts match-idx] + (update-in parts [match-idx] replacement)) + parts (range 1 (count parts) 2)))) + (.. regex (matcher string) (replaceAll replacement)))) (defn re-sub "Replaces the first instance of 'pattern' in 'string' with - 'replacement'. Like Ruby's 'String#sub'." + 'replacement'. Like Ruby's 'String#sub'. + + If (ifn? replacement) is true, the replacement is called with + the match. + " [#^Pattern regex replacement #^String string] - (.. regex (matcher string) (replaceFirst replacement))) + (if (ifn? replacement) + (let [m (re-matcher regex string)] + (if (.find m) + (str (.subSequence string 0 (.start m)) + (replacement (re-groups m)) + (.subSequence string (.end m) (.length string))) + string)) + (.. regex (matcher string) (replaceFirst replacement)))) + (defn str-join "Returns a string of all elements in 'sequence', separated by diff --git a/src/clojure/contrib/test_contrib/str_utils.clj b/src/clojure/contrib/test_contrib/str_utils.clj new file mode 100644 index 00000000..812821dc --- /dev/null +++ b/src/clojure/contrib/test_contrib/str_utils.clj @@ -0,0 +1,33 @@ +(ns clojure.contrib.test-contrib.str-utils + (:use clojure.contrib.test-is + clojure.contrib.str-utils)) + + +(deftest test-re-gsub + (let [re #"\%([0-9a-fA-F]{2})" + replacement (fn [match] + (char (Integer/parseInt + (match 1) 16)))] + (is (= (re-gsub re replacement "") "")) + (is (= (re-gsub re replacement "%20") " ")) + (is (= (re-gsub re replacement "x%20") "x ")) + (is (= (re-gsub re replacement "x%20%0a") "x \n")) + (is (= (re-gsub re replacement "x%20y") "x y")) + (is (= (re-gsub re "?" "") "")) + (is (= (re-gsub re "?" "%21") "?")) + (is (= (re-gsub re "?" "x%22") "x?")) + (is (= (re-gsub re "?" "x%23y") "x?y")))) + +(deftest test-re-sub + (let [re #"\%([0-9a-fA-F]{2})" + replacement (fn [match] + (char (Integer/parseInt + (match 1) 16)))] + (is (= (re-sub re replacement "") "")) + (is (= (re-sub re replacement "%20") " ")) + (is (= (re-sub re replacement "x%20%20") "x %20")) + (is (= (re-sub re replacement "x%20y") "x y")) + (is (= (re-sub re "?" "") "")) + (is (= (re-sub re "?" "%21") "?")) + (is (= (re-sub re "?" "x%22%25") "x?%25")) + (is (= (re-gsub re "?" "x%23y") "x?y")))) |