{{clojure.string/split}} with a limit can not correctly split a string as following:
(clojure.string/split "quaqb" #"q(?!u)") ; <- match a 'q' not followed by a 'u'
;;=> ["qua" "b"]
(clojure.string/split "quaqb" #"q(?!u)" 2)
;;=> ["" "uaqb"]
the result of the first case is what we want, but the result of second case is wrong.
because, if there is a limit, it split a string using a own routine instead of a {{String.prototype.split}} function of JavaScript.
and the routine have a problem when using [Lookaehad or Lookbehind|
https://www.regular-expressions.info/lookaround.html] in the regular expression.
;; clojure.string/split:
(let [re #"q(?!u)"]
(loop [s "quaqb"
limit 2
parts []]
(if (== 1 limit)
(conj parts s)
(let [m (re-find re s)] ; <- 1!
(if-not (nil? m)
(let [index (.indexOf s m)] ; <- 2!
(recur (.substring s (+ index (count m)))
(dec limit)
(conj parts (.substring s 0 index))))
(conj parts s))))))
;;=> ["" "uaqb"]
(re-find #"q(?!u)" "quaqb") ; <- 1!
;; => "q"
(.indexOf "quaqb" "q") ; <- 2!
;;=> 0
we should get a index from {{RegExp.prototype.exec}} function of JavaScript instead of calculating a index.
;; clojure.string/split:
(let [re #"q(?!u)"]
(loop [s "quaqb"
limit 2
parts []]
(if (== 1 limit)
(conj parts s)
(let [m (.exec re s)]
(if-not (nil? m)
(let [index (.-index m)]
(recur (.substring s (+ index (count (aget m 0))))
(dec limit)
(conj parts (.substring s 0 index))))
(conj parts s))))))
;;=> ["qua" "b"]
i tested on V8, Spidermonkey, Nashorn.