From: q u a s i
Subject: string splitting problem
Date: 
Message-ID: <94gktv4hk1l6p93nkss70l0jm7lnebpn1s@4ax.com>
Folks,

Am at my wits end.

I have to split a string from /proc/net/arp of the format
"127.0.0.1       0x1  0x2     00:11:22:33:AE:5E        *    ethx"
                                  ^^^
to extract the MAC.

I have looked and looked .. tried Wade's suggestion (and other's) from
this thread
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&threadm=xcvvghhpw95.fsf%40conquest.OCF.Berkeley.EDU&rnum=2&prev=/groups%3Fq%3Dsplitting%2Ba%2Bstring%2Bgroup:comp.lang.lisp.*%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26group%3Dcomp.lang.lisp.*%26selm%3Dxcvvghhpw95.fsf%2540conquest.OCF.Berkeley.EDU%26rnum%3D2

but always I get stuck because of the colons.  "Too many colons" is
the error.

any help would be welcome ... it is 3:48am and I am stuck.  My first
attempt of using CL at work. I used C earlier and there it was a
fscanf(file, "%s ....", ,)...  Is there any equivalent to ?scanf in CL
?

thanks

--
quasi
http://abhijit-rao.tripod.com/

From: Thomas A. Russ
Subject: Re: string splitting problem
Date: 
Message-ID: <ymiptettvm9.fsf@sevak.isi.edu>
  If you can use Open Source (Gnu GPL) software, look at Sam Steingold's
solution:

  
http://cvs.sourceforge.net/viewcvs.py/clocc/clocc/src/cllib/string.lisp?rev=1.3

Alternately, search the history of this newsgroup for SPLIT-STRING or
SPLIT-SEQUENCE and look at those solutions.


-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Thomas F. Burdick
Subject: Re: string splitting problem
Date: 
Message-ID: <xcvwu914b9d.fsf@famine.OCF.Berkeley.EDU>
q u a s i <·········@yahoo.com> writes:

> Folks,
> 
> Am at my wits end.
> 
> I have to split a string from /proc/net/arp of the format
> "127.0.0.1       0x1  0x2     00:11:22:33:AE:5E        *    ethx"
>                                   ^^^
> to extract the MAC.
> 
> I have looked and looked .. tried Wade's suggestion (and other's) from
> this thread
> http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&threadm=xcvvghhpw95.fsf%40conquest.OCF.Berkeley.EDU&rnum=2&prev=/groups%3Fq%3Dsplitting%2Ba%2Bstring%2Bgroup:comp.lang.lisp.*%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26group%3Dcomp.lang.lisp.*%26selm%3Dxcvvghhpw95.fsf%2540conquest.OCF.Berkeley.EDU%26rnum%3D2
> 
> but always I get stuck because of the colons.  "Too many colons" is
> the error.

I don't get what you mean when you say "'too many colons' is the
error."  It would be more helpful to show what you have, because it's
not obvious where you're stuck.  Are you having trouble seperating out
the MAC part?  Or are you having trouble parsing the MAC once you have it?

I'm pretty ignorant of the format we're talking about, but you could
probably do something along the lines of:

  (defun parse-arp-line (line &key (format '(:ip :* :* :hw-addr :mask :device)))
    (let ((alist ()))
      (do-splitting-vector ((start end (line #\Space)))
        (when (> (- start end) 0)
          (push (cons (pop format) (subseq line start end))
                alist)))
      alist))

Although I'm guessing those aren't really spaces, like in your
message, but tabs, in which case you could use something like:

  (defun parse-arp-line (line &key (format '(:ip :* :* :hw-addr :mask :device)))
    (let ((alist ()))
      (do-splitting-vector (start end (line #\Tab))
        (push (cons (pop format) (subseq line start end))
              alist))
      alist))

Or maybe fields are fixed-width, in which case you should just break
it up directly with subseq:

  (defmacro with-fixed-records ((&rest specs) line &body forms)
    (let ((=line (gensym))
          (start-vars (loop repeat (length specs) collect (gensym)))
          (end-vars (loop repeat (length specs) collect (gensym))))
      `(let ,(loop for svar in start-vars
                   for evar in end-vars
                   for (rec-var start end) in specs
                   collect `(,svar ,start)
                   collect `(,evar ,end))
         (let ((,=line ,line))
           (let ,(loop for start in start-vars
                       for end in end-vars
                       for (rec-var) in specs
                       collect `(,rec-var (subseq ,=line ,start ,end)))
             ,@forms)))))

Using this, the following:

  (with-fixed-records ((ip 0 16)
                       (mac 29 46))
                      arp-line
    ...)

would expand into:

  (let ((#:g1 0) (#:g3 16) (#:g2 29) (#:g4 46))
    (let ((#:g0 arp-line))
      (let ((ip (subseq #:g0 #:g1 #:g3))
            (mac (subseq #:g0 #:g2 #:g4)))
        ...)))

Hope this is helpful.  If not, show us your best attempt.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: q u a s i
Subject: Re: string splitting problem
Date: 
Message-ID: <7tbltvk9vmj2of02rne2gvvu21hokhk3o1@4ax.com>
On 12 Dec 2003 20:01:02 -0800, ···@famine.OCF.Berkeley.EDU (Thomas F.
Burdick) wrote:

>q u a s i <·········@yahoo.com> writes:
[ excellent instructive material ]
>
>Hope this is helpful.  If not, show us your best attempt.

Thanks.  That was most helpfull and has given me whole new ideas.
Especially the with-fixed-records macro :).

But a little while after I posted here I lost my net connection and
the desperation made me remembered cl-ppcre and cl-ppcre:split solved
the problem.  The problem was that whatever methods I was using were
throwing a error while parsing the colons embedded in the string.  It
seemed such a simple thing that it drove me crazy. :-)

thanks again all for the ideas,



--
quasi
http://abhijit-rao.tripod.com/
From: Håkon Alstadheim
Subject: Re: string splitting problem
Date: 
Message-ID: <m0ekuamdqi.fsf@alstadhome.dyndns.org>
q u a s i <·········@yahoo.com> writes:

> The problem was that whatever methods I was using were
> throwing a error while parsing the colons embedded in the string.  It
> seemed such a simple thing that it drove me crazy. :-)

You should not assume people are mind-readers. The best thing to do in
this kind of situation is to show the shortest, self-contained code
you have that demonstrates the error.

Now, with my mind-reading hat on I'm guessing that you were using READ
or READ-FROM-STRING to parse the line. With a format like the one you
are reading, you would need to mess with the read-table to make `:'
not be a package:symbol delimiter. That is for advanced coders only.
With the format you have it is much simpler to just get the raw
characters into a string, maybe with READ-LINE or READ-SEQUENCE, and
parse it yourself.

-- 
H�kon Alstadheim, hjemmepappa.
From: Peter Seibel
Subject: Re: string splitting problem
Date: 
Message-ID: <m3n08w4zl9.fsf@javamonkey.com>
······@online.no (H�kon Alstadheim) writes:

> q u a s i <·········@yahoo.com> writes:
> 
> > The problem was that whatever methods I was using were
> > throwing a error while parsing the colons embedded in the string.  It
> > seemed such a simple thing that it drove me crazy. :-)
> 
> You should not assume people are mind-readers. The best thing to do in
> this kind of situation is to show the shortest, self-contained code
> you have that demonstrates the error.
> 
> Now, with my mind-reading hat on I'm guessing that you were using READ
> or READ-FROM-STRING to parse the line. With a format like the one you
> are reading, you would need to mess with the read-table to make `:'
> not be a package:symbol delimiter. That is for advanced coders only.

Except, depending what you're trying to do, you may not be able to
modify the read-table the way you want. #\: is a consituent character
(which you could change) but it's its constituent trait that makes it
a package marker. But, per 2.1.4.2, "no mechanism is provided for
changing the constituent trait of a character."

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: james anderson
Subject: Re: string splitting problem
Date: 
Message-ID: <3FDA4AB0.4F5786D1@setf.de>
? (defparameter *rt* (copy-readtable))
*RT*
? (set-syntax-from-char #\. #\space *rt*)
T
? (set-syntax-from-char #\: #\space *rt*)

T
? (with-input-from-string (stream "127.0.0.1       0x1  0x2    
00:11:22:33:AE:5E        *    ethx
")
  (let ((v nil) (list nil) (*readtable* *rt*))
    (loop (unless (setf v (read stream nil nil)) (return (nreverse list)))
          (push v list))))
(127 0 0 1 0X1 0X2 0 11 22 33 AE 5E * ETHX)
? 

q u a s i wrote:
> 
> Folks,
> 
> Am at my wits end.
> 
> I have to split a string from /proc/net/arp of the format
> "127.0.0.1       0x1  0x2     00:11:22:33:AE:5E        *    ethx"
>                                   ^^^
> to extract the MAC.
> ...
> 
> but always I get stuck because of the colons.  "Too many colons" is
> the error.
> 
> any help would be welcome ... it is 3:48am and I am stuck.  My first
> attempt of using CL at work. I used C earlier and there it was a
> fscanf(file, "%s ....", ,)...  Is there any equivalent to ?scanf in CL
> ?
> 
> thanks
> 
> --
> quasi
> http://abhijit-rao.tripod.com/
From: larry
Subject: Re: string splitting problem
Date: 
Message-ID: <7b8f89d6.0312121917.27611ee2@posting.google.com>
Hey that's pretty cool, but how about this way, using loop collect so
you dont'have to call nreverse

(defun splitstr(str)
  (with-input-from-string  (stream str)
    (let ((list nil) 
          (*readtable* (copy-readtable)))
      (set-syntax-from-char #\. #\space *readtable*)
      (set-syntax-from-char #\: #\space *readtable*)
      (loop for x = (read stream nil nil) until (not x)
            collect x))))


james anderson <··············@setf.de> wrote in message news:<·················@setf.de>...
> ? (defparameter *rt* (copy-readtable))
> *RT*
> ? (set-syntax-from-char #\. #\space *rt*)
> T
> ? (set-syntax-from-char #\: #\space *rt*)
> 
> T
> ? (with-input-from-string (stream "127.0.0.1       0x1  0x2    
> 00:11:22:33:AE:5E        *    ethx
> ")
>   (let ((v nil) (list nil) (*readtable* *rt*))
>     (loop (unless (setf v (read stream nil nil)) (return (nreverse list)))
>           (push v list))))
> (127 0 0 1 0X1 0X2 0 11 22 33 AE 5E * ETHX)
> ? 
> 
> q u a s i wrote:
> > 
> > Folks,
> > 
> > Am at my wits end.
> > 
> > I have to split a string from /proc/net/arp of the format
> > "127.0.0.1       0x1  0x2     00:11:22:33:AE:5E        *    ethx"
> >                                   ^^^
> > to extract the MAC.
> > ...
> > 
> > but always I get stuck because of the colons.  "Too many colons" is
> > the error.
> > 
> > any help would be welcome ... it is 3:48am and I am stuck.  My first
> > attempt of using CL at work. I used C earlier and there it was a
> > fscanf(file, "%s ....", ,)...  Is there any equivalent to ?scanf in CL
> > ?
> > 
> > thanks
> > 
> > --
> > quasi
> > http://abhijit-rao.tripod.com/
From: Pascal Bourguignon
Subject: Re: string splitting problem
Date: 
Message-ID: <878ylho9ic.fsf@thalassa.informatimago.com>
q u a s i <·········@yahoo.com> writes:

> Folks,
> 
> Am at my wits end.
> 
> I have to split a string from /proc/net/arp of the format
> "127.0.0.1       0x1  0x2     00:11:22:33:AE:5E        *    ethx"
>                                   ^^^
> to extract the MAC.


When I don't need the utmost efficient solution, I merely use:

[69]> (split-string  (fourth (delete "" (split-string line " ")  
                              :test (function string=))) ":")
("00" "11" "22" "33" "AE" "5E")


with (GPL sources):

(DEFUN SPLIT-STRING (STRING &OPTIONAL (SEPARATORS " "))
  "
NOTE:   current implementation only accepts as separators
        a string containing literal characters.
"
  (UNLESS (SIMPLE-STRING-P STRING)     (SETQ STRING     (COPY-SEQ STRING)))
  (UNLESS (SIMPLE-STRING-P SEPARATORS) (SETQ SEPARATORS (COPY-SEQ SEPARATORS)))
  (LET ((CHUNKS  '())
        (POSITION 0)
        (NEXTPOS  0)
        (STRLEN   (LENGTH STRING)) )
    (DECLARE (TYPE SIMPLE-STRING STRING SEPARATORS))
    (LOOP WHILE (< POSITION STRLEN)
          DO
          (LOOP WHILE (AND (< NEXTPOS STRLEN)
                           (not (position (CHAR STRING NEXTPOS) separators)))
                DO (SETQ NEXTPOS (1+ NEXTPOS))
                );;loop
          (PUSH (SUBSEQ STRING POSITION NEXTPOS) CHUNKS)
          (SETQ POSITION (1+ NEXTPOS))
          (SETQ NEXTPOS  POSITION)
          );;loop
    (NREVERSE CHUNKS)
    );;let
  );;SPLIT-STRING


(DEFUN UNSPLIT-STRING (STRING-LIST &OPTIONAL SEPARATOR)
  "
DO:         The inverse than split-string.
            If no separator is provided then a simple space is used.
SEPARATOR:  (OR NULL STRINGP CHARACTERP)
"
  (COND
   ((NULL SEPARATOR)
    (SETQ SEPARATOR " "))
   ((CHARACTERP SEPARATOR)
    (SETQ SEPARATOR (MAKE-STRING 1 :INITIAL-ELEMENT SEPARATOR)))
   ((NOT (STRINGP SEPARATOR))
    (ERROR "unsplit-string: separator must be a string or a char.")))
  (APPLY 'CONCATENATE 'STRING (LIST-INSERT-SEPARATOR STRING-LIST SEPARATOR))
  );;UNSPLIT-STRING

 
-- 
__Pascal_Bourguignon__                              .  *   * . * .* .
http://www.informatimago.com/                        .   *   .   .*
There is no worse tyranny than to force             * .  . /\  ()  . *
a man to pay for what he does not                    . .  / .\   . * .
want merely because you think it                    .*.  / *  \  . .
would be good for him. -- Robert Heinlein             . /*   o \     .
http://www.theadvocates.org/                        *   '''||'''   .
SCO Spam-magnet: ··········@sco.com                 ******************
From: Edi Weitz
Subject: Re: string splitting problem
Date: 
Message-ID: <8765gljva2.fsf@bird.agharta.de>
On Sat, 13 Dec 2003 04:00:00 +0530, q u a s i <·········@yahoo.com> wrote:

> I have to split a string

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

Or try one of the CL regex libraries. Most (all?) of them have a split
facility:

  <http://www.cliki.net/Regular%20Expression>

Edi.
From: q u a s i
Subject: Re: string splitting problem
Date: 
Message-ID: <qnbltv431t5s0nij23do5uqj9mc6qusbfs@4ax.com>
On Sat, 13 Dec 2003 03:39:33 +0100, Edi Weitz <···@agharta.de> wrote:

>On Sat, 13 Dec 2003 04:00:00 +0530, q u a s i <·········@yahoo.com> wrote:
>
>> I have to split a string
>
>  <http://www.cliki.net/SPLIT-SEQUENCE>
>
>Or try one of the CL regex libraries. Most (all?) of them have a split
>facility:
>
>  <http://www.cliki.net/Regular%20Expression>

3 minutes after I posted here I remembered cl-ppcre.  cl-ppcre:split
did the trick.

Thanks :-)

>
>Edi.


--
quasi
http://abhijit-rao.tripod.com/