PDA

View Full Version : (code) extract number from string



Mark Thomas
18th Jan 2005, 02:01 pm
(defun extract-nums (str /
; local functions
is-num is-char parselst
; local variables
cntr x str_lst new_lst lst_of_lst final_lst
)
;;; FUNCTION
;;; returns a list of reals from a given string
;;; function does _not_ check argument type
;;;
;;; example; given the string "one 12 two 22.3 three .55 four 2.255"
;;; the function would return (12.0 22.3 0.55 2.255)
;;;
;;; ARGUMENTS
;;; str = string
;;;
;;; USAGE
;;; (setq lst_of_reals (extract-nums "str"))
;;;
;;; PLATFORMS
;;; 2000+
;;;
;;; AUTHOR
;;; Copyright 2004 Mark S. Thomas
;;; mark_at_theswamp.org
;;;
;;; VERSION
;;; 1.0

;; returns T if 'n' falls between 48 and 57
;; ascii characters 0-9
(defun is-num (n)
&#40;and &#40;> n 47&#41; &#40;< n 58&#41;&#41;
&#41;

;; returns T if 'n' is _not_ between 48 and 57 or 46
;; all ascii characters other than 0-9 and '.'&#40;dot/period&#41;
&#40;defun is-char &#40;n&#41;
&#40;not &#40;or &#40;and &#40;> n 47&#41;&#40;< n 58&#41;&#41; &#40;= n 46&#41;&#41;&#41;
&#41;

;; Stig Madsen
;; returns a list of lists delimited by 'delim'
;; example
;; given the list '&#40;12 0 32 56 0 45&#41; where '0' is the delimiter
;; &#40;parselst 0 '&#40;12 0 32 56 0 45&#41;&#41;
;; return would be &#40;&#40;12&#41;&#40;32 56&#41;&#40;45&#41;&#41;
&#40;defun parselst &#40;delim lst / l ll&#41;
&#40;while lst
&#40;cond
&#40;&#40;not &#40;eq &#40;car lst&#41; delim&#41;&#41;
&#40;setq l &#40;cons &#40;car lst&#41; l&#41;&#41;
&#41;
&#40;&#40;setq ll &#40;if l &#40;cons &#40;reverse l&#41; ll&#41; ll&#41; l nil&#41;
&#41;
&#41;
&#40;setq lst &#40;cdr lst&#41;&#41;
&#41;
&#40;reverse &#40;if l &#40;cons &#40;reverse l&#41; ll&#41; ll&#41;&#41;
&#41;

;; ================== main starts here =======================

&#40;setq str_lst &#40;vl-string->list str&#41;
cntr 0
&#41;

&#40;while &#40;setq x &#40;nth cntr str_lst&#41;&#41;
&#40;cond
&#40;&#40;= x 46&#41; ; <dot>
&#40;if &#40;is-num &#40;nth &#40;1+ cntr&#41; str_lst&#41;&#41;; next n is a num
&#40;setq new_lst &#40;cons x new_lst&#41;&#41;
&#41;
&#41;
&#40;&#40;is-num x&#41;
&#40;setq new_lst &#40;cons x new_lst&#41;&#41;
&#40;if &#40;is-char &#40;nth &#40;1+ cntr&#41; str_lst&#41;&#41;; next n is not a num
&#40;setq new_lst &#40;cons 32 new_lst&#41;&#41;
&#41;
&#41;
&#40;&#40;= x 32&#41; ; <space>
&#40;if &#40;is-num &#40;nth &#40;1+ cntr&#41; str_lst&#41;&#41;; next n is a num
&#40;setq new_lst &#40;cons x new_lst&#41;&#41;
&#41;
&#41;
&#40;&#40;= x 80&#41; ;


&#40;if &#40;is-num &#40;nth &#40;1+ cntr&#41; str_lst&#41;&#41;
&#40;setq new_lst &#40;cons 32 new_lst&#41;&#41;
&#41;
&#41;
&#41;; cond

&#40;setq cntr &#40;1+ cntr&#41;&#41;
&#41;; while

&#40;if new_lst
&#40;progn
&#40;setq lst_of_lst &#40;parselst 32 &#40;reverse new_lst&#41;&#41;
final_lst &#40;mapcar 'atof &#40;mapcar 'vl-list->string lst_of_lst&#41;&#41;
&#41;
&#41;
&#41;
&#41;

;; test function
&#40;defun c&#58;e2sl &#40;/ ent txt&#41;
&#40;if &#40;setq ent &#40;car &#40;entsel "\nSelect text&#58; "&#41;&#41;&#41;
&#40;if &#40;setq txt &#40;cdr &#40;assoc 1 &#40;entget ent&#41;&#41;&#41;&#41;
&#40;extract-nums txt&#41;
&#41;
&#41;
&#41;