From: Nir Sullam
Subject: String parse to list ??
Date: 
Message-ID: <7ir305$hlq$1@lnews.actcom.co.il>
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]

From: Kent M Pitman
Subject: Re: String parse to list ??
Date: 
Message-ID: <sfwbtf24cw4.fsf@world.std.com>
"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.
From: Marco Antoniotti
Subject: Re: String parse to list ??
Date: 
Message-ID: <lw1zfxsmcx.fsf@copernico.parades.rm.cnr.it>
"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
From: Arthur Lemmens
Subject: Re: String parse to list ??
Date: 
Message-ID: <375284B9.251C222B@simplex.nl>
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")
     ""))