summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/clj/clojure/string.clj130
-rw-r--r--test/clojure/test_clojure/string.clj53
2 files changed, 183 insertions, 0 deletions
diff --git a/src/clj/clojure/string.clj b/src/clj/clojure/string.clj
new file mode 100644
index 00000000..a82d6c6c
--- /dev/null
+++ b/src/clj/clojure/string.clj
@@ -0,0 +1,130 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+
+(ns ^{:doc "String utilities"
+ :author "Stuart Sierra"}
+ clojure.string
+ (:refer-clojure :exclude (replace reverse))
+ (:import (java.util.regex Pattern)))
+
+(defn #^String reverse
+ "Returns s with its characters reversed."
+ [#^String s]
+ (.toString (.reverse (StringBuilder. s))))
+
+(defn replace-str
+ "Replaces all instances of substring a with b in s."
+ [#^String a #^String b #^String s]
+ (.replace s a b))
+
+(defn replace-char
+ "Replaces all instances of character a with character b in s."
+ [#^Character a #^Character b #^String s]
+ (.replace s a b))
+
+(defn replace-re
+ "Replaces all matches of re with replacement in s."
+ [re replacement #^String s]
+ (.replaceAll (re-matcher re s) replacement))
+
+(defn replace-by
+ "Replaces all matches of re in s with the result of
+ (f (re-groups the-match))."
+ [re f #^String s]
+ (let [m (re-matcher re s)]
+ (let [buffer (StringBuffer. (.length s))]
+ (loop []
+ (if (.find m)
+ (do (.appendReplacement m buffer (f (re-groups m)))
+ (recur))
+ (do (.appendTail m buffer)
+ (.toString buffer)))))))
+
+(defn replace-first-str
+ "Replace first occurance of substring a with b in s."
+ [#^String a #^String b #^String s]
+ (.replaceFirst (re-matcher (Pattern/quote a) s) b))
+
+(defn replace-first-re
+ "Replace first match of re in s."
+ [#^Pattern re #^String replacement #^String s]
+ (.replaceFirst (re-matcher re s) replacement))
+
+(defn replace-first-by
+ "Replace first match of re in s with the result of
+ (f (re-groups the-match))."
+ [#^Pattern re f #^String s]
+ (let [m (re-matcher re s)]
+ (let [buffer (StringBuffer.)]
+ (if (.find m)
+ (let [rep (f (re-groups m))]
+ (.appendReplacement m buffer rep)
+ (.appendTail m buffer)
+ (str buffer))))))
+
+(defn #^String join
+ "Returns a string of all elements in coll, separated by
+ separator. Like Perl's join."
+ [#^String separator coll]
+ (apply str (interpose separator coll)))
+
+(defn #^String chop
+ "Removes the last character of string, does nothing on a zero-length
+ string."
+ [#^String s]
+ (let [size (count s)]
+ (if (zero? size)
+ s
+ (subs s 0 (dec (count s))))))
+
+(defn #^String chomp
+ "Removes all trailing newline \\n or return \\r characters from
+ string. Note: String.trim() is similar and faster."
+ [#^String s]
+ (replace-re #"[\r\n]+$" "" s))
+
+(defn #^String capitalize
+ "Converts first character of the string to upper-case, all other
+ characters to lower-case."
+ [#^String s]
+ (if (< (count s) 2)
+ (.toUpperCase s)
+ (str (.toUpperCase #^String (subs s 0 1))
+ (.toLowerCase #^String (subs s 1)))))
+
+(defn #^String ltrim
+ "Removes whitespace from the left side of string."
+ [#^String s]
+ (replace-re #"^\s+" "" s))
+
+(defn #^String rtrim
+ "Removes whitespace from the right side of string."
+ [#^String s]
+ (replace-re #"\s+$" "" s))
+
+(defn #^String upper-case
+ "Converts string to all upper-case."
+ [#^String s]
+ (.toUpperCase s))
+
+(defn #^String lower-case
+ "Converts string to all lower-case."
+ [#^String s]
+ (.toLowerCase s))
+
+(defn split
+ "Splits string on a regular expression. Optional argument limit is
+ the maximum number of splits."
+ ([#^Pattern re #^String s] (seq (.split re s)))
+ ([#^Pattern re limit #^String s] (seq (.split re s limit))))
+
+(defn #^String trim
+ "Removes whitespace from both ends of string."
+ [#^String s]
+ (.trim s))
+
diff --git a/test/clojure/test_clojure/string.clj b/test/clojure/test_clojure/string.clj
new file mode 100644
index 00000000..255e47a6
--- /dev/null
+++ b/test/clojure/test_clojure/string.clj
@@ -0,0 +1,53 @@
+(ns clojure.test-clojure.string
+ (:require [clojure.string :as s])
+ (:use clojure.test))
+
+(deftest t-reverse
+ (is (= "tab" (s/reverse "bat"))))
+
+(deftest t-replace
+ (is (= "faabar" (s/replace-char \o \a "foobar")))
+ (is (= "barbarbar" (s/replace-str "foo" "bar" "foobarfoo")))
+ (is (= "FOObarFOO" (s/replace-by #"foo" s/upper-case "foobarfoo"))))
+
+(deftest t-replace-first
+ (is (= "barbarfoo" (s/replace-first-re #"foo" "bar" "foobarfoo")))
+ (is (= "FOObarfoo" (s/replace-first-by #"foo" s/upper-case "foobarfoo"))))
+
+(deftest t-join
+ (is (= "1,2,3" (s/join \, [1 2 3])))
+ (is (= "" (s/join \, [])))
+ (is (= "1 and-a 2 and-a 3" (s/join " and-a " [1 2 3]))))
+
+(deftest t-chop
+ (is (= "fo" (s/chop "foo")))
+ (is (= "") (s/chop "f"))
+ (is (= "") (s/chop "")))
+
+(deftest t-chomp
+ (is (= "foo" (s/chomp "foo\n")))
+ (is (= "foo" (s/chomp "foo\r\n")))
+ (is (= "foo" (s/chomp "foo")))
+ (is (= "" (s/chomp ""))))
+
+(deftest t-capitalize
+ (is (= "Foobar" (s/capitalize "foobar")))
+ (is (= "Foobar" (s/capitalize "FOOBAR"))))
+
+(deftest t-ltrim
+ (is (= "foo " (s/ltrim " foo ")))
+ (is (= "" (s/ltrim " "))))
+
+(deftest t-rtrim
+ (is (= " foo" (s/rtrim " foo ")))
+ (is (= "" (s/rtrim " "))))
+
+(deftest t-trim
+ (is (= "foo" (s/trim " foo \r\n"))))
+
+(deftest t-upper-case
+ (is (= "FOOBAR" (s/upper-case "Foobar"))))
+
+(deftest t-lower-case
+ (is (= "foobar" (s/lower-case "FooBar"))))
+