First, let's format the code conventionally, so everyone can read it more easily.
- Code: Select all
(defun string-split (split-pattern string)
(let ((n 0)
(l (length split-pattern)))
(loop
(setf pos (search split-pattern string :start2 n))
(if pos
((collect (subseq string n pos))
(setf n (+ pos l))))
(collect (subseq string n)))))
Loop isn't as perceptive as you think. It won't understand if you nest
collects like that. (
Iterate is a bit more understanding.)
Here is a solution which uses more of loop's features. I hope I'm not spoiling it for you.
- Code: Select all
(defun string-split (split-pattern string)
(loop for start = 0 then (+ match (length split-pattern))
for match = (search split-pattern string :start2 start)
collect (subseq string start match)
while match))
If you want to use a more
setf-based style, this should help you get started. As you clearly know, the intuition is that you want to collect everything from your starting point to... as far as you can go.
(If you want to be robust, you can check what happens if
split-pattern is an empty string, and stop that from happening.)