Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java/clojure: Multiple character delimiter, and keep the delimiter

I'm working on a project in clojure, which can interop with any java classes, so the answer to my question could be for either java or clojure.

Basically I need to be able to split a string into components based on a given delimiter (which will be more then one character) but at the same time keep the delimiters.

For example:

splitting "test:test:test" on ":"  => [ "test" ":" "test" ":" "test" ]
splitting "::test::test::" on "::" => [ "::" "test" "::" "test" "::" ]

The closets I've come use using clojure's clojure.string/split, but it doesn't actually return the delimiters. The second closest was using StringTokenizer, which does return the delimiters but doesn't accept multi-character delimiters.

Does anyone know of any solutions other then just breaking the string into a sequence of characters and running a weird reduce on it?

like image 536
Mediocre Gopher Avatar asked Mar 08 '13 04:03

Mediocre Gopher


2 Answers

Here's a version that builds a regex to match the gaps before and after the delimiters, instead of the delimiter string itself (assuming no regex special chars in d):

=> (defn split-with-delim [s d]
     (clojure.string/split s (re-pattern (str "(?=" d ")|(?<=" d ")"))))
#'user/split-with-delim
=> (split-with-delim "test:test:test" ":")
["test" ":" "test" ":" "test"]
=> (split-with-delim "::test::test::" "::")
["" "::" "test" "::" "test" "::"]
like image 59
OpenSauce Avatar answered Sep 20 '22 10:09

OpenSauce


(defn split-it [s d]
  (interpose d (str/split s (re-pattern d))))

(split-it "test:test:test" ":")
=> ("test" ":" "test" ":" "test")

(split-it "::test::test::" "::")
=> ("" "::" "test" "::" "test")
like image 24
mobyte Avatar answered Sep 17 '22 10:09

mobyte