* How to parse a string?
@ 2003-04-30 23:42 François Fleuret
2003-05-01 1:54 ` Greg Hill
[not found] ` <mailman.5430.1051754378.21513.help-gnu-emacs@gnu.org>
0 siblings, 2 replies; 7+ messages in thread
From: François Fleuret @ 2003-04-30 23:42 UTC (permalink / raw)
Hi,
Maybe is this a dumb question, but I do not see how to find the answer
either in the info files or on the web.
I just want to do a primitive parsing scanf-style in elisp.
For instance, given a string which I know is composed of 5 fields of
type integer/integer/word/word/word, separated by spaces, how can I
transform this string into a list of the objects?
Thanks in advance,
FF
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: How to parse a string?
2003-04-30 23:42 How to parse a string? François Fleuret
@ 2003-05-01 1:54 ` Greg Hill
[not found] ` <mailman.5430.1051754378.21513.help-gnu-emacs@gnu.org>
1 sibling, 0 replies; 7+ messages in thread
From: Greg Hill @ 2003-05-01 1:54 UTC (permalink / raw)
At 1:42 AM +0200 5/1/03, François Fleuret wrote:
>For instance, given a string which I know is composed of 5 fields of
>type integer/integer/word/word/word, separated by spaces, how can I
>transform this string into a list of the objects?
(let ((instring "10 20 wordA wordB wordC"))
(setq instring (split-string instring))
(append (list (string-to-number (pop instring))
(string-to-number (pop instring)))
instring))
--Greg
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: How to parse a string?
[not found] ` <mailman.5430.1051754378.21513.help-gnu-emacs@gnu.org>
@ 2003-05-01 9:56 ` Francois Fleuret
2003-05-01 12:00 ` Kai Großjohann
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Francois Fleuret @ 2003-05-01 9:56 UTC (permalink / raw)
Hi,
Greg Hill wrote on 01 May 2003 02:54:20 MET:
> (let ((instring "10 20 wordA wordB wordC"))
> (setq instring (split-string instring))
> (append (list (string-to-number (pop instring))
> (string-to-number (pop instring)))
> instring))
Thanks a lot!
But is there a generic way to do such a thing ? No scanf equivalent
around ?
FF
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: How to parse a string?
2003-05-01 9:56 ` Francois Fleuret
@ 2003-05-01 12:00 ` Kai Großjohann
2003-05-01 18:02 ` Greg Hill
2003-05-01 21:10 ` Pascal Bourguignon
2 siblings, 0 replies; 7+ messages in thread
From: Kai Großjohann @ 2003-05-01 12:00 UTC (permalink / raw)
Francois Fleuret <francois.fleuret@inria.fr> writes:
> But is there a generic way to do such a thing ? No scanf equivalent
> around ?
You can do it with buffers. In fact, it is not at all unusual to
create a buffer just to process one line. And if, instead of killing
the buffer and making a new one for the next string, you just keep the
buffer around and use it again for the next string, it's really fast.
For a buffer, you have lots of quite powerful functions, such as
THING-at-point (number-at-point, word-at-point, ...).
--
file-error; Data: (Opening input file no such file or directory ~/.signature)
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: How to parse a string?
2003-05-01 9:56 ` Francois Fleuret
2003-05-01 12:00 ` Kai Großjohann
@ 2003-05-01 18:02 ` Greg Hill
2003-05-01 21:10 ` Pascal Bourguignon
2 siblings, 0 replies; 7+ messages in thread
From: Greg Hill @ 2003-05-01 18:02 UTC (permalink / raw)
At 11:56 AM +0200 5/1/03, Francois Fleuret wrote:
>But is there a generic way to do such a thing ? No scanf equivalent
>around ?
Not as standard Emacs Lisp, but no doubt someone has written their
own. I'm surprised nobody has replied by giving you a web page where
you could find one.
It wouldn't be hard to write one for yourself, and then you can make
it behave any way you like. Here is something quick and dirty I just
hacked together to demonstrate what I mean. It takes a "format
string" as the first argument, and the string to be parsed as the
second. Each character in the format string tells how to translate
one "word" in the string to be parsed, where:
i = integer
f = float
n = number (integer or float, don't care)
s = string
anything else = skip
(defun scanf (format string)
(let ((list nil) fmt word)
(setq string (split-string string)
format (split-string format ""))
(while (and string format)
(setq word (pop string)
fmt (pop format))
(cond ((equal fmt "i")
(setq word (floor (string-to-number word))))
((equal fmt "f")
(setq word (float (string-to-number word))))
((equal fmt "n")
(setq word (string-to-number word)))
((not (equal fmt "s"))
(setq word nil)))
(if word (setq list (append list (list word)))))
list))
Use it like this:
(scanf "ifsxnn" "1 2.3 word skip 4 5.6")
==> (1 2.3 "word" 4 5.6)
Now go ahead and be a real Emacser. Cook up your own function work
any way you like.
--Greg
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: How to parse a string?
2003-05-01 9:56 ` Francois Fleuret
2003-05-01 12:00 ` Kai Großjohann
2003-05-01 18:02 ` Greg Hill
@ 2003-05-01 21:10 ` Pascal Bourguignon
2003-05-01 23:41 ` Greg Hill
2 siblings, 1 reply; 7+ messages in thread
From: Pascal Bourguignon @ 2003-05-01 21:10 UTC (permalink / raw)
Francois Fleuret <francois.fleuret@inria.fr> writes:
> Hi,
>
> Greg Hill wrote on 01 May 2003 02:54:20 MET:
>
> > (let ((instring "10 20 wordA wordB wordC"))
> > (setq instring (split-string instring))
> > (append (list (string-to-number (pop instring))
> > (string-to-number (pop instring)))
> > instring))
>
> Thanks a lot!
>
> But is there a generic way to do such a thing ? No scanf equivalent
> around ?
>
> FF
Just encapsulate the line with '( ... ):
(defun scanf (string) ;; no need to specify the format and the variable,
"We return a list of item scanned from the string."
(read (concat "( " string " )")))
(dolist (item (scanf "10 20 3.33 wordA wordB wordC"))
(show item (type-of item)))
==> (10 integer)
==> (20 integer)
==> (3.33 float)
==> (wordA symbol)
==> (wordB symbol)
==> (wordC symbol)
--
__Pascal_Bourguignon__ http://www.informatimago.com/
----------------------------------------------------------------------
Do not adjust your mind, there is a fault in reality.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: How to parse a string?
2003-05-01 21:10 ` Pascal Bourguignon
@ 2003-05-01 23:41 ` Greg Hill
0 siblings, 0 replies; 7+ messages in thread
From: Greg Hill @ 2003-05-01 23:41 UTC (permalink / raw)
At 11:10 PM +0200 5/1/03, Pascal Bourguignon wrote:
>Francois Fleuret <francois.fleuret@inria.fr> writes:
> > But is there a generic way to do such a thing ? No scanf equivalent
> > around ?
>Just encapsulate the line with '( ... ):
>
> (defun scanf (string) ;; no need to specify the format and the variable,
> "We return a list of item scanned from the string."
> (read (concat "( " string " )")))
>
>(dolist (item (scanf "10 20 3.33 wordA wordB wordC"))
> (show item (type-of item)))
>
>==> (10 integer)
>==> (20 integer)
>==> (3.33 float)
>==> (wordA symbol)
>==> (wordB symbol)
>==> (wordC symbol)
Nice trick, if you want the strings read as symbols. If you're
looking for strings, how about:
(defun scanf (string)
"We return a list of items scanned from the string."
(mapcar (lambda (x) (if (symbolp x) (symbol-name x) x))
(read (concat "( " string " )"))))
By the way, where is that "show" function defined? I presume it is
effectively:
(defun show (&rest args) (princ "==> ") (princ args) (terpri))
--Greg
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2003-05-01 23:41 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-04-30 23:42 How to parse a string? François Fleuret
2003-05-01 1:54 ` Greg Hill
[not found] ` <mailman.5430.1051754378.21513.help-gnu-emacs@gnu.org>
2003-05-01 9:56 ` Francois Fleuret
2003-05-01 12:00 ` Kai Großjohann
2003-05-01 18:02 ` Greg Hill
2003-05-01 21:10 ` Pascal Bourguignon
2003-05-01 23:41 ` Greg Hill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).