From: Nikola Skoric
Subject: string searching functions in CL
Date: 
Message-ID: <MPG.1eb6e97caa7c5b1298969f@news.t-com.hr>
Hi there,

I can't seem to find functions for searching a string in Common Lisp. 
I'd like to do such a simple thing as finding out if a string has a 
substring in it, but can't seem to find a function to do that. Am I 
blind or what?

Yes, of course it's easy to write one myself, its just that I can't 
belive there's not such function CL...

-- 
"Now the storm has passed over me
I'm left to drift on a dead calm sea
And watch her forever through the cracks in the beams
Nailed across the doorways of the bedrooms of my dreams" 

From: Marco Baringer
Subject: Re: string searching functions in CL
Date: 
Message-ID: <m2lktvm8df.fsf@bese.it>
Nikola Skoric <·········@net4u.hr> writes:

> Hi there,
>
> I can't seem to find functions for searching a string in Common Lisp. 
> I'd like to do such a simple thing as finding out if a string has a 
> substring in it, but can't seem to find a function to do that. Am I 
> blind or what?

search - http://www.lisp.org/HyperSpec/Body/fun_search.html

see also cl-ppcre (http://www.weitz.de/cl-ppcre/)

-- 
-Marco
Ring the bells that still can ring.
Forget the perfect offering.
There is a crack in everything.
That's how the light gets in.
	-Leonard Cohen
From: Nikola Skoric
Subject: Re: string searching functions in CL
Date: 
Message-ID: <MPG.1eb6ec48a426f2c19896a0@news.t-com.hr>
In article <··············@bese.it>, ··@bese.it says...
> Nikola Skoric <·········@net4u.hr> writes:
> 
> > Hi there,
> >
> > I can't seem to find functions for searching a string in Common Lisp. 
> > I'd like to do such a simple thing as finding out if a string has a 
> > substring in it, but can't seem to find a function to do that. Am I 
> > blind or what?
> 
> search - http://www.lisp.org/HyperSpec/Body/fun_search.html
> 
> see also cl-ppcre (http://www.weitz.de/cl-ppcre/)

OK, OK, I hate being a n00b. I forgot that strings are sequences and 
that functions for sequences work on strings.

And, now one for which I won't be surprised if ti didn't exist: a 
function to explode a string in a PHP's manner. That is, (explode " " 
"foo bar") returns ("foo" "bar"). Does something like that exist? I 
promise this is my last dumb question for next 2 months ;-)

-- 
"Now the storm has passed over me
I'm left to drift on a dead calm sea
And watch her forever through the cracks in the beams
Nailed across the doorways of the bedrooms of my dreams" 
From: Peter Seibel
Subject: Re: string searching functions in CL
Date: 
Message-ID: <m264kz86ap.fsf@gigamonkeys.com>
Nikola Skoric <·········@net4u.hr> writes:

> In article <··············@bese.it>, ··@bese.it says...
>> Nikola Skoric <·········@net4u.hr> writes:
>> 
>> > Hi there,
>> >
>> > I can't seem to find functions for searching a string in Common Lisp. 
>> > I'd like to do such a simple thing as finding out if a string has a 
>> > substring in it, but can't seem to find a function to do that. Am I 
>> > blind or what?
>> 
>> search - http://www.lisp.org/HyperSpec/Body/fun_search.html
>> 
>> see also cl-ppcre (http://www.weitz.de/cl-ppcre/)
>
> OK, OK, I hate being a n00b. I forgot that strings are sequences and 
> that functions for sequences work on strings.
>
> And, now one for which I won't be surprised if ti didn't exist: a 
> function to explode a string in a PHP's manner. That is, (explode " " 
> "foo bar") returns ("foo" "bar"). Does something like that exist? I 
> promise this is my last dumb question for next 2 months ;-)

Nope. But the SPLIT-SEQUENCE library does what you want:

  <http://www.cliki.net/SPLIT-SEQUENCE>

-Peter

-- 
Peter Seibel           * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp  * http://www.gigamonkeys.com/book/
From: Marco Baringer
Subject: Re: string searching functions in CL
Date: 
Message-ID: <m2hd4jm80x.fsf@bese.it>
Nikola Skoric <·········@net4u.hr> writes:

> In article <··············@bese.it>, ··@bese.it says...
>> Nikola Skoric <·········@net4u.hr> writes:
>> 
>> > Hi there,
>> >
>> > I can't seem to find functions for searching a string in Common Lisp. 
>> > I'd like to do such a simple thing as finding out if a string has a 
>> > substring in it, but can't seem to find a function to do that. Am I 
>> > blind or what?
>> 
>> search - http://www.lisp.org/HyperSpec/Body/fun_search.html
>> 
>> see also cl-ppcre (http://www.weitz.de/cl-ppcre/)
>
> OK, OK, I hate being a n00b. I forgot that strings are sequences and 
> that functions for sequences work on strings.
>
> And, now one for which I won't be surprised if ti didn't exist: a 
> function to explode a string in a PHP's manner. That is, (explode " " 
> "foo bar") returns ("foo" "bar"). Does something like that exist? I 
> promise this is my last dumb question for next 2 months ;-)

that does not in fact exist. what you have is this:

http://www.cliki.net/SPLIT-SEQUENCE

it's a very small lib, has been stable for a long time and is used by
a bunch of other libs.

-- 
-Marco
Ring the bells that still can ring.
Forget the perfect offering.
There is a crack in everything.
That's how the light gets in.
	-Leonard Cohen
From: tichy
Subject: Re: string searching functions in CL
Date: 
Message-ID: <1146044957.641870.327010@t31g2000cwb.googlegroups.com>
> http://www.cliki.net/SPLIT-SEQUENCE
>
> it's a very small lib, has been stable for a long time and is used by
> a bunch of other libs.

Nice, but VERY slow when input is a list.
Naive wersion (works only on lists):

(defun split-list-if (list test &aux (start list) (end list))
  (loop while (and end (setq start (member-if-not test end)))
        collect (ldiff start (setq end (member-if test start)))))

;;; Speed test:

CL-USER> (defparameter *test-data*
           (with-open-file (stream
#P"/home/tichy/emacs/man/man1/emacs.1"
                            :direction :input)
             (loop with char while (setq char (read-char stream nil
nil))
                   collect char)))
CL-USER> (length *test-data*)
15837
CL-USER> (defvar *test-result*)
CL-USER> (defun test-split-list-if ()
           (setq *test-result*
                 (split-list-if *test-data*
                                (lambda (x)
                                  (member x '(#\Space #\Newline
#\Tab)))))
           (values))
CL-USER> (defun test-split-sequence-if ()
           (setq *test-result*
                 (cl-utilities:split-sequence-if
                  (lambda (x) (member x '(#\Space #\Newline #\Tab)))
                  *test-data*
                  :remove-empty-subseqs t))
           (values))
CL-USER> (time (test-split-list-if))
Evaluation took:
  0.001 seconds of real time
  0.001 seconds of user run time               ; !!!
  0.0 seconds of system run time
  0 page faults and
  147,456 bytes consed.
; No value
CL-USER> (time (test-split-sequence-if))
Evaluation took:
  0.746 seconds of real time
  0.744 seconds of user run time               ; !!!
  0.0 seconds of system run time
  0 page faults and
  131,072 bytes consed.
; No value

Regards, Szymon.
From: keyboard
Subject: Re: string searching functions in CL
Date: 
Message-ID: <1145930421.078521.143910@e56g2000cwe.googlegroups.com>
Nikola Skoric schrieb:

> In article <··············@bese.it>, ··@bese.it says...
> > Nikola Skoric <·········@net4u.hr> writes:
> >
> > > Hi there,
> > >
> > > I can't seem to find functions for searching a string in Common Lisp.
> > > I'd like to do such a simple thing as finding out if a string has a
> > > substring in it, but can't seem to find a function to do that. Am I
> > > blind or what?
> >
> > search - http://www.lisp.org/HyperSpec/Body/fun_search.html
> >
> > see also cl-ppcre (http://www.weitz.de/cl-ppcre/)
>
> OK, OK, I hate being a n00b. I forgot that strings are sequences and
> that functions for sequences work on strings.
>
> And, now one for which I won't be surprised if ti didn't exist: a
> function to explode a string in a PHP's manner. That is, (explode " "
> "foo bar") returns ("foo" "bar"). Does something like that exist? I
> promise this is my last dumb question for next 2 months ;-)
>
> --
> "Now the storm has passed over me
> I'm left to drift on a dead calm sea
> And watch her forever through the cracks in the beams
> Nailed across the doorways of the bedrooms of my dreams"

try this:

(defun tokens (str test start)
  "Find tokens in STR separated by TEST from position START."
  (let ((p1 (position-if test str :start start)))
   (if p1
       (let ((p2 (position-if #'(lambda (c)
                                  (not (funcall test c)))
                              str :start p1)))
         (cons (subseq str p1 p2)
               (if p2
                   (tokens str test p2)
                   nil)))
       nil)))

(defun constituent (c)
  "the separating function"
  (and (graphic-char-p c)
       (not (char= c #\  ))))

(defun find-character (char string)
  "See if the character appears in the string."
  (declare (character char) (simple-string string))
  (loop for ch across string
        when (eql ch char) return ch))

[26]> (tokens "a clock is running" #'constituent 0)
("a" "clock" "is" "running")

keyboard
From: py-ggroup
Subject: Re: string searching functions in CL
Date: 
Message-ID: <1145948897.574523.251330@u72g2000cwu.googlegroups.com>
keyboard wrote:
> Nikola Skoric schrieb:
>
> > In article <··············@bese.it>, ··@bese.it says...
> > > Nikola Skoric <·········@net4u.hr> writes:
> > >
> > > > Hi there,
> > > >
> > > > I can't seem to find functions for searching a string in Common Lisp.
> > > > I'd like to do such a simple thing as finding out if a string has a
> > > > substring in it, but can't seem to find a function to do that. Am I
> > > > blind or what?
> > >
> > > search - http://www.lisp.org/HyperSpec/Body/fun_search.html
> > >
> > > see also cl-ppcre (http://www.weitz.de/cl-ppcre/)
> >
> > OK, OK, I hate being a n00b. I forgot that strings are sequences and
> > that functions for sequences work on strings.
> >
> > And, now one for which I won't be surprised if ti didn't exist: a
> > function to explode a string in a PHP's manner. That is, (explode " "
> > "foo bar") returns ("foo" "bar"). Does something like that exist? I
> > promise this is my last dumb question for next 2 months ;-)
> >
> > --
> > "Now the storm has passed over me
> > I'm left to drift on a dead calm sea
> > And watch her forever through the cracks in the beams
> > Nailed across the doorways of the bedrooms of my dreams"
>
> try this:
>
> (defun tokens (str test start)
>   "Find tokens in STR separated by TEST from position START."
>   (let ((p1 (position-if test str :start start)))
>    (if p1
>        (let ((p2 (position-if #'(lambda (c)
>                                   (not (funcall test c)))
>                               str :start p1)))
>          (cons (subseq str p1 p2)
>                (if p2
>                    (tokens str test p2)
>                    nil)))
>        nil)))
>
> (defun constituent (c)
>   "the separating function"
>   (and (graphic-char-p c)
>        (not (char= c #\  ))))
>
> (defun find-character (char string)
>   "See if the character appears in the string."
>   (declare (character char) (simple-string string))
>   (loop for ch across string
>         when (eql ch char) return ch))
>
> [26]> (tokens "a clock is running" #'constituent 0)
> ("a" "clock" "is" "running")
> 
> keyboard
From: tichy
Subject: Re: string searching functions in CL
Date: 
Message-ID: <1145984418.551938.163630@e56g2000cwe.googlegroups.com>
Version with LOOP is shorter:

(defun tokens (str test &optional (start 0) &aux (end 0))
  (loop while (and end (setq start (position-if test str :start end)))
          collect (subseq str start (setq end (position-if-not test str
:start start)))))

CL-USER> (tokens "a clock is running" #'constituent)
("a" "clock" "is" "running")

Btw, there is function CHAR/= (equivalent of (NOT (CHAR= ...))).

Another variation:

(defun split-string-on-char (string char)
  (loop with (start end) = '(0 0)
          while (and end (setq start (position-if (lambda (c) (char/=
char c)) string :start end)))
          collect (subseq string start (setq end (position char string
:start start)))))

CL-USER> (split-string-on-char "a clock is running" #\Space)
("a" "clock" "is" "running")

Regards, Szymon.
From: Rob Warnock
Subject: Re: string searching functions in CL
Date: 
Message-ID: <VYCdnczs48NVQtDZnZ2dnUVZ_sednZ2d@speakeasy.net>
Marco Baringer  <··@bese.it> wrote:
+---------------
| Nikola Skoric <·········@net4u.hr> writes:
| > I'd like to do such a simple thing as finding out if a string has a 
| > substring in it, but can't seem to find a function to do that.
| 
| search - http://www.lisp.org/HyperSpec/Body/fun_search.html
| see also cl-ppcre (http://www.weitz.de/cl-ppcre/)
+---------------

Don't forget MISMATCH <http://www.lisp.org/HyperSpec/Body/fun_mismatch.html>
I actually tend to find myself using it rather more than SEARCH
for simple pattern matches, deconstructions, and peeling off
prefixes & suffixes. Further, alternating calls of MISMATCH and
SEARCH are often useful, using the results of each call in the
:START or [with :FROM-END T] :END keyword args in the next call.

-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607