Hello
Is there any CL built-in function to take a comma\space deleimited string
and make a list out of it ?
I don't want you to send me one - if there is ot - I will create it.
TIA
Nir Sullam [CL Novice]
"Nir Sullam" <······@actcom.co.il> writes:
> Is there any CL built-in function to take a comma\space deleimited string
> and make a list out of it ?
No.
> I don't want you to send me one - if there is ot - I will create it.
This is a common question, btw.
The ALU web pages or DejaNews may find it for you fastest.
I'm sure I've seen it addressed here.
"Nir Sullam" <······@actcom.co.il> writes:
> Hello
>
> Is there any CL built-in function to take a comma\space deleimited string
> and make a list out of it ?
>
> I don't want you to send me one - if there is ot - I will create it.
>
Tricky question. :) Are there interspersed whitespaces in the string?
What about
"e1,e2, e3, e4,<tab>e5"
You get the idea. If this is the case you need at least a lexer to get
the job done. Otherwise there have been a few SPLIT-STRING that
appeared on CLL.
Cheers
--
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - 06 68 10 03 17, fax. +39 - 06 68 80 79 26
http://www.parades.rm.cnr.it/~marcoxa
Nir Sullam:
> Is there any CL built-in function to take a comma\space delimited string
> and make a list out of it ?
Marco Antoniotti:
> Tricky question. :) Are there interspersed whitespaces in the string?
> What about
>
> "e1,e2, e3, e4,<tab>e5"
>
> You get the idea. If this is the case you need at least a lexer to get
> the job done.
I don't see why you'd need "at least a lexer" here.
Maybe I'm missing something?
> Otherwise there have been a few SPLIT-STRING that
> appeared on CLL.
Here's what I use these days.
It's inspired by something Bernard Pfahringer posted a few months ago.
It handles your example nicely.
(defun SPLIT (delimiter seq
&key (maximum nil)
(keep-empty-subseqs nil)
(from-end nil)
(start 0)
(end nil)
(test nil test-supplied)
(test-not nil test-not-supplied)
(key nil key-supplied))
"Return a list of subsequences in <seq> delimited by <delimiter>.
If :keep-empty-subseqs is true, empty subsequences will be included
in the result; otherwise they will be discarded.
If :maximum is supplied, the result will contain no more than :maximum
(possibly empty) subsequences. The second result value contains the
unsplit rest of the sequence.
All other keywords work analogously to those for CL:POSITION."
;; DO: Make ":keep-delimiters t" include the delimiters in the result
(?).
(let ((len (length seq)))
(unless end (setq end len))
;; DO: Find a more efficient way to take care of :from-end T.
(when from-end
(setf seq (reverse seq))
(psetf start (- len end)
end (- len start)))
(loop with other-keys = (nconc (when test-supplied
(list :test test))
(when test-not-supplied
(list :test-not test-not))
(when key-supplied
(list :key key)))
for left = start then (+ right 1)
for right = (min (or (apply #'position delimiter seq
:start left
other-keys)
len)
end)
unless (and (= right left) ; empty-subsequence
(not keep-empty-subseqs))
if (and maximum (>= nr-elts maximum))
;; We can't take any more. Return now.
return (values subseqs (subseq seq left end))
else
collect (subseq seq left right) into subseqs
and sum 1 into nr-elts
until (= right end)
finally return (values subseqs (subseq seq right end)))))
(defun SPLIT-IF (predicate seq &rest keys)
"SPLIT-IF is to SPLIT what POSITION-IF is to POSITION"
(apply #'split nil seq
:test (lambda (ignore x)
(declare (ignore ignore))
(funcall predicate x))
keys))
(defun SPLIT-IF-NOT (predicate seq &rest keys)
"SPLIT-IF-NOT is to SPLIT what POSITION-IF-NOT is to POSITION"
(apply #'split nil seq
:test-not (lambda (ignore x)
(declare (ignore ignore))
(funcall predicate x))
keys))
(examples (SPLIT SPLIT-IF SPLIT-IF-NOT)
; DO: Verify that all other keyword-args work.
(=> (split #\space "word1 word2 word3")
'("word1" "word2" "word3")
"")
(=> (split #\; "12;13;;14" :keep-empty-subseqs t)
'("12" "13" "" "14")
"")
(=> (split t '(a t b t))
'((a) (b))
'())
(=> (split-if (complement #'alphanumericp) "25.11.1987")
'("25" "11" "1987")
"")
(=> (split-if-not #'alphanumericp "25.11.1987")
'("25" "11" "1987")
"")
(=> (split #\space "%A This is a test." :maximum 1)
'("%A")
"This is a test.")
(=> (split #\space "Nospaceshere")
'("Nospaceshere")
"")
(=> (split-if #'(lambda (char) (or (char= char #\space)
(char= char #\,)
(char= char #\tab)))
"e1,e2, e3, e4, e5")
("e1" "e2" "e3" "e4" "e5")
""))