gsc Posted October 16, 2018 Posted October 16, 2018 Hi, I want to split a string where the "underscore" is the split character. example: (setq str "vessel_name_type") I want the "name" in a separate variable. Note: The amount of characters of "name" and "type" may vary. How do I do this? Greetzzz, Gerben Quote
rlx Posted October 16, 2018 Posted October 16, 2018 classic... ;;; s = string d = delimiter p = position delimiter (thanx Lee Mac) (defun SplitStr ( s d / p ) (if (setq p (vl-string-search d s)) (cons (substr s 1 p) (SplitStr (substr s (+ p 1 (strlen d))) d)) (list s))) Quote
hanhphuc Posted October 16, 2018 Posted October 16, 2018 (setq str "vessel_name_type") (setq lst (read (strcat "("(vl-string-translate "_" " " str)")"))) '(VESSEL NAME TYPE) ; symbol as variable ? note: TYPE is a protected symbol (mapcar 'vl-princ-to-string lst) '("VESSEL" "NAME" "TYPE") ; or string list? Quote
Grrr Posted October 16, 2018 Posted October 16, 2018 CAB's sparser Lee's: ; _$ (LM:str->lst "the good the bad man and the ugly..." "the ") >> ("" "good " "bad man and " "ugly...") (defun LM:str->lst ( str del / pos ) (if (setq pos (vl-string-search del str)) (cons (substr str 1 pos) (LM:str->lst (substr str (+ pos 1 (strlen del))) del)) (list str) ) ) This one, from my subs: ; Written by Grrr ; _$ (mapcar '(lambda (x) (_SplitStr "x" x)) '("150" "150x320" "60x60x" "75x75x75" "x1234xxx422xx1" "x" "")) ; >> ("150" ("150" "x" "320") ("60" "x" "60" "x") ("75" "x" "75" "x" "75") ("x" "1234" "x" "x" "x" "422" "x" "x" "1") ("x") "") (setq _SplitStr '( ( c s / L cL ) (cond ( (not (eq 'STR (type s))) nil) ( (member (setq c (ascii c)) (setq cL (vl-string->list s))) (reverse (apply 'append (mapcar ''( (x / tmp) (cond ( (not x) (if L (list (vl-list->string L))) ) ( (= c x) (setq tmp L) (setq L nil) (append (if tmp (list (vl-list->string tmp))) (list (chr c))) ) ( (setq L (cons x L)) nil ) ) ) (reverse (cons nil cL)) ) ) ) ) ( s ) ) ) ); setq _SplitStr Quote
gsc Posted October 16, 2018 Author Posted October 16, 2018 (edited) Thanx people! all work like a charm Edited October 16, 2018 by gsc Quote
Grrr Posted October 16, 2018 Posted October 16, 2018 (edited) Another, for practice: ;| _$ (split "hello world!" "l") >> ("he" "l" "l" "o wor" "l" "d!") _$ (split "hello world!" "") >> nil _$ (split "hello world!" "@") >> "hello world!" _$ (split "hellhellolllo world!" "l") >> ("he" "l" "l" "he" "l" "l" "o" "l" "l" "l" "o wor" "l" "d!") |; (defun split ( s d ) ( (lambda (f) (if (/= "" d) (f s d "" nil))) (lambda ( s d c b / k ) (if (/= s "") (if (= d (setq k (substr s 1 1))) (append (cond ( (/= c "") (list c d) ) ( (list d) ) ) (f (substr s 2) d "" t) ) (f (substr s 2) d (strcat c k) b) ) (if b (list c) c) ) ) ) ); defun split ; (test) >> ("vessel" "" "name" "" "type" "") (defun test ( / rgx r ) (if (setq rgx (vlax-get-or-create-object "VBScript.Regexp")) (progn (foreach x '((Global . acTrue)(Multiline . acTrue)(Pattern . "[^_]*")) (vlax-put-property rgx (car x) (eval (cdr x))) ) (vlax-for o (vlax-invoke-method rgx 'Execute "vessel_name_type") (setq r (cons (vlax-get-property o 'Value) r))) ) ) (and rgx (vlax-release-object rgx)) (reverse r) ) Edited October 17, 2018 by Grrr fixed Quote
dlanorh Posted October 16, 2018 Posted October 16, 2018 and another. (defun rh:str_split (str char lst / pos ) (setq lst (cons (substr str 1 (setq pos (vl-string-position (ascii char) str))) lst) str (substr str (+ 2 pos)) ) (if (vl-string-position (ascii char) str) (rh:str_split str char lst) (setq lst (reverse (cons str lst)))) ) (setq v_name (nth 1 (rh:str_split "vessel_name_type" "_" nil))) Quote
Jef! Posted October 16, 2018 Posted October 16, 2018 @hanhphuc Depending on the scenario, your version might have a side effect. While (setq str "vessel_name_type") is the given category sample, since you change delimiters for spaces, any string containing a space itself would get split as well. (setq str "Boat_Santa Maria_Destroyer") would return ("BOAT" "SANTA" "MARIA" "DESTROYER"). With the read approach it also change the case of the strings too, which might or might not be an issue. Everyone else went recursive... here'S my iterative version (defun Jef!:splitstr (delim str / nxt ep ret) (setq nxt (1+ (strlen delim))) (while (setq ep (vl-string-search delim str)) (setq ret (cons (substr str 1 ep)ret)) (setq str (substr str (+ nxt (strlen (car ret))) (strlen str))) ) (reverse(cons str ret)) ) Cheers! 1 Quote
hanhphuc Posted October 17, 2018 Posted October 17, 2018 (edited) On 10/17/2018 at 5:17 AM, Jef! said: @hanhphuc Depending on the scenario, your version might have a side effect. While (setq str "vessel_name_type") is the given category sample, since you change delimiters for spaces, any string containing a space itself would get split as well @Jef! yes agree. my intention was merely a simple way for OP's str "vessel_name_type" i should have mentioned that, thanks anyway Here's the previous thread 3 different tests. foo - iteration VL list<->string bar - substr recursion LM or rlx posted above baz - list evaluation (This was the bug/side effect which you mentioned ** ) (setq str ", ,,#101,123.456,789.345,45.789,XYZ, ,, ,") _$ (foo str) ;("" " " "" "#101" "123.456" "789.345" "45.789" "XYZ" " " "" " ") _$ (bar str) ;("" " " "" "#101" "123.456" "789.345" "45.789" "XYZ" " " "" " " "") _$ (baz str) ;("#101" "123.456" "789.345" "45.789" "XYZ") _$ (baz "123 456,789 XYZ");** ;("123" "456" "789" "XYZ") a simple fix - temporary switches "\255" with " " blank, not a best solution but just for alternative idea. (setq l (list "vessel_name_type" "vessel_name type" '(f $) '(mapcar ''(($) (f "\255" " " $)) (read (strcat "(" (f " _" "\255 " $) ")")))) f (cddr l)) ;test OP's str "vessel_name_type" ( f vl-string-translate (car l) ) '("VESSEL" "NAME" "TYPE") ;test OP's str with a space "vessel_name type" ( f vl-string-translate (cadr l) ) '("VESSEL" "NAME TYPE") ; solve? hiccup is strcase cheers Edited October 17, 2018 by hanhphuc add examples Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.