Here is another solution that avoids the problems with repetitive patterns and double recognitions present in leetwinski's answer (see my comments) and also computes the parts lazily-as-possible:
(defn partition-str [s sep]
(->> s
(re-seq
(->> sep
java.util.regex.Pattern/quote ; remove this to treat sep as a regex
(format "((?s).*?)(?:(%s)|\\z)")
re-pattern))
(mapcat rest)
(take-while some?)
(remove empty?))) ; remove this to keep empty parts
HOWEVER this does not behave correctly/intuitively when the separator is/matches the empty string.
Another way could be to use both re-seq
and split
with the same pattern and interleave the resulting sequences as shown in this related question. Unfortunately this way every occurrence of the separator will be recognized twice.
Perhaps a better approach would be to build on a more primitive basis using re-matcher
and re-find
.
Finally, to offer a straighter answer to the initial question, there is no such function in Clojure's standard library or any external library AFAIK. Moreover I don't know of any simple and completely unproblematic solution to this problem (especially with a regex-separator).
UPDATE
Here is the best solution I can think of right now, working on a lower level, lazily and with a regex-separator:
(defn re-partition [re s]
(let [mr (re-matcher re s)]
((fn rec [i]
(lazy-seq
(if-let [m (re-find mr)]
(list* (subs s i (.start mr)) m (rec (.end mr)))
(list (subs s i)))))
0)))
(def re-partition+ (comp (partial remove empty?) re-partition))
Notice that we can (re)define:
(def re-split (comp (partial take-nth 2) re-partition))
(def re-seq (comp (partial take-nth 2) rest re-partition))