Jump to content
gsc

How to split a string by character

Recommended Posts

gsc

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

Share this post


Link to post
Share on other sites
rlx

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)))

 

Share this post


Link to post
Share on other sites
hanhphuc
(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?

 

Share this post


Link to post
Share on other sites
Grrr

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

 

Share this post


Link to post
Share on other sites
gsc

Thanx people! all work like a charm

 

 

Edited by gsc

Share this post


Link to post
Share on other sites
Grrr

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 by Grrr
fixed

Share this post


Link to post
Share on other sites
dlanorh

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)))

 

Share this post


Link to post
Share on other sites
Jef!

@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!

  • Thanks 1

Share this post


Link to post
Share on other sites
hanhphuc
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 by hanhphuc
add examples

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×