Jump to content

How to split a string by character


gsc

Recommended Posts

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

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

(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?

 

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

@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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...