Hi!
Sorry for the delay, I was on vacation.
Oh, and please use the mailing list - see Cc.
On Sat, 3 Jun 2006 22:28:29 +0200, "Alexander Kjeldaas" alexander.kjeldaas@gmail.com wrote:
I'm a big fan of register-groups-bind. For some longer texts that I'm parsing, I have code that looks like this:
The idiom is - you want to go through the text matching various regexps, but you want to keep on to the end-position in order to do incremental matching. So I added an :end-holder keyword parameter that is the name of a variable that is set to the end-match (I also added :start-holder, but I don't use it).
To me, this type of parsing is relatively simple to debug, but it is also not too sloppy in that we don't start from the beginning all the time.
:end-place and :start-place might be better names, I don't know..
I think that the idea is basically OK, but I'm not sure if I like that seemingly END-POS is supposed to be an existing variable which is set - I think it'd be more Lisp-y to bind within the body of the form. Admittedly, the indentation would get quite nasty then.
Cheers, Edi.
(defun parse-stuff (string) "Parse various account information" (let ((result nil) end-pos) (register-groups-bind (foo) ("Kontoinformasjon for (.*)\s+" string :end-holder end-pos) (push `(:username ,foo) result)) (register-groups-bind (foo) ("Navn:[ \t]+(.*)\s+" string :start end-pos :end-holder end-pos) (push `(:name ,foo) result)) ;; Use (?=Telefon) to not affect the end-position. (register-groups-bind (addr1 addr2 addr3) ("Adresse:[ \t]+(.*)\s+(?:(.*)\s+)?(?:(.*)\s+)?(?=Telefon)" string :start end-pos :end-holder end-pos) (push (remove-if-not #'identity `(:address ,addr1 ,addr2 ,addr3)) result)) (register-groups-bind (foo) ("Telefon:[ \t]+(\+?\d+)" string :start end-pos :end-holder end-pos) (push `(:phone ,foo) result)) (register-groups-bind (foo) ("Mobil:[ \t]+(\+?\d+)" string :start end-pos :end-holder end-pos) (push `(:mobile-phone ,foo) result)) (register-groups-bind (foo) ("Epost:[ \t]+(.*)\n" string :start end-pos :end-holder end-pos) (push `(:email ,foo) result)) (register-groups-bind (foo) ("Epost:[ \t]+(.*)\n" string :start end-pos :end-holder end-pos) (push `(:email ,foo) result)) (nreverse result)))