Jump to content

Recommended Posts

Posted

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

Posted

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

 

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

 

Posted

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

 

Posted (edited)

Thanx people! all work like a charm

 

 

Edited by gsc
Posted (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 by Grrr
fixed
Posted

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

 

Posted

@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
Posted (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 by hanhphuc
add examples

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