String Help

String Help

Travis.Biddle
Advocate Advocate
1,232 Views
21 Replies
Message 1 of 22

String Help

Travis.Biddle
Advocate
Advocate

I have a string ("P01-1_P02-2_P03-3").

I need to break the string down so I can compare the ("P01-1_P02-2_P03-3") and see if the values are equal.  The format is always the same with the exception that P01 may be WM01 (example string P01-1_WM02-2).  The dashes and underscores always remain the same.  I cant figure out how to strip the string from start up to the dash, and then from the underscore to the dash, repeating until the end of the string.

 

Any help is much appreciated!

0 Likes
Accepted solutions (3)
1,233 Views
21 Replies
Replies (21)
Message 2 of 22

ВeekeeCZ
Consultant
Consultant
Accepted solution
(defun ParseBy_then- (str / LM:str->lst)

;; String to List  -  Lee Mac
;; http://www.lee-mac.com/stringtolist.html
;; Separates a string using a given delimiter
;; str - [str] String to process
;; del - [str] Delimiter by which to separate the string
;; Returns: [lst] List of strings
 
(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)
    )
)

(mapcar '(lambda (sub) (LM:str->lst sub "-")) (LM:str->lst str "_")))

>> (parseby_then- "P01-1_P02-2_P03-3")
>> (("P01" "1") ("P02" "2") ("P03" "3"))

 

You can add (mapcar 'Car lst) to get a list of P's.

0 Likes
Message 3 of 22

Travis.Biddle
Advocate
Advocate

Work great, thank you so much!!  One additional question...

 

I used the (mapcar 'Car lst) to get the list of "P's"... Do you know of a way to easily check to see if all the elements in this list are equal?  I need to do 2 different things depending on if they are all equal of not.

0 Likes
Message 4 of 22

Kent1Cooper
Consultant
Consultant

@Travis.Biddle wrote:

.... Do you know of a way to easily check to see if all the elements in this list are equal?  ....


(apply '= '("P01" "P01" "P01"))
T

(apply '= '("P01" "P02" "P03"))
nil

Kent Cooper, AIA
Message 5 of 22

ВeekeeCZ
Consultant
Consultant
Accepted solution

yep,

(if (apply '= lst)

  (same)...

looks good.

0 Likes
Message 6 of 22

Travis.Biddle
Advocate
Advocate

I found this in my research, but for some reason I am getting "T" result with the code below.  In this example, variable NEWLIST2 = ("P01" "P02" "P03"), where am I going wrong?

 

(setq
newlist (mapcar '(lambda (sub) (LM:str->lst sub "-")) (LM:str->lst str "_"))
newlist2 (mapcar 'Car newlist)
len1 (length newlist2)
Same (apply '= '(newlist2))
)

0 Likes
Message 7 of 22

Kent1Cooper
Consultant
Consultant

@Travis.Biddle wrote:

....

Same (apply '= '(newlist2))
....


That should be just (apply '= newlist2).

Kent Cooper, AIA
0 Likes
Message 8 of 22

Travis.Biddle
Advocate
Advocate

I was attempting to set the results of the (apply '= newlist2) to a variable defined as SAME for an If/then statement later in the routine.  something like...

 (if (= same T)
(do this)
(or do this)

)

 

Is there a way to set the results of (apply '= newlist2)?

 

0 Likes
Message 9 of 22

Kent1Cooper
Consultant
Consultant
Accepted solution

@Travis.Biddle wrote:

I was attempting to set the results of the (apply '= newlist2) to a variable defined as SAME for an If/then statement later in the routine.

Is there a way to set the results of (apply '= newlist2)?


With the correction in Message 7 to the line quoted there, you should have it already in your multiple-variable (setq) function.  The value will be either T or nil.  It's not necessary to test whether it is "equal to T" -- you can simply test whether it exists at all, because any value other than nil will satisfy the (if) test:

 

(if same
  (then -- do this)
  (else -- do that)

)

Kent Cooper, AIA
0 Likes
Message 10 of 22

Travis.Biddle
Advocate
Advocate

Ahh, I see. Thank you guys so much!!

0 Likes
Message 11 of 22

Travis.Biddle
Advocate
Advocate

what is causing this to run automatically when loaded?  I have never came across this before that I can recall.  All my programs are typically called out by function after being loaded.

0 Likes
Message 12 of 22

ВeekeeCZ
Consultant
Consultant

Nothing. This code does not run on load.

0 Likes
Message 13 of 22

Kent1Cooper
Consultant
Consultant

@Travis.Biddle wrote:

what is causing this to run automatically when loaded?  ....


The only thing I can think of that might cause that would be if you copied the code from below the commentary lines, without including the

(defun ParseBy_then- (str / LM:str->lst)

header line.  Then loading it would just run the contained code, and not define a function.  [But there should be an extra-right-parenthesis message.]  If that's what happened, then trying to use it:

  (parseby_then- "P01-1_P02-2_P03-3")

would give a no-function-definition error.

Kent Cooper, AIA
0 Likes
Message 14 of 22

Travis.Biddle
Advocate
Advocate

This is the code as I have it currently..

 

(defun c:ParseBy_then- (str / LM:str->lst)

;; String to List - Lee Mac
;; http://www.lee-mac.com/stringtolist.html
;; Separates a string using a given delimiter
;; str - [str] String to process
;; del - [str] Delimiter by which to separate the string
;; Returns: [lst] List of strings

(setq selpt1 '(9334.559 -1477.997));;setting points for window selection
(setq selpt2 '(13249.704 2820.847));;setting points for window selection
(setq ss (ssget "W" selpt1 selpt2 '((0 . "TEXT")(8 . "FILENAME"))));;selecting a single text string on FILENAME layer
(setq vobject (vlax-ename->vla-object (ssname ss 0)))
(setq str (vla-get-textstring vobject));;setting the string to process below
(setq del "_") ;; setting the delimiter for below

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

(setq newlist (mapcar '(lambda (sub) (lm:str->lst sub "-")) (lm:str->lst str "_")))
)

 

If I run through this line by line, copying fromt he code to the command line it works.  If I load the program and execute command "C:ParseBy_Then-"   I get a "too few arguments error"

0 Likes
Message 15 of 22

ВeekeeCZ
Consultant
Consultant

What are you going to do next with the separated text?

0 Likes
Message 16 of 22

Travis.Biddle
Advocate
Advocate

3 different things depending on the separated list results.  

   a. if the list length is 1, do A

   b. if the list length is not 1, and each item in the list is equal, do B

   c. if the list length is not 1, and the items are not equal, do C

0 Likes
Message 17 of 22

ВeekeeCZ
Consultant
Consultant

@Travis.Biddle wrote:

This is the code as I have it currently..

 

(defun c:ParseBy_then- (str / LM:str->lst)  ; this is cousing the error

;; String to List - Lee Mac
;; http://www.lee-mac.com/stringtolist.html
;; Separates a string using a given delimiter
;; str - [str] String to process
;; del - [str] Delimiter by which to separate the string
;; Returns: [lst] List of strings

(setq selpt1 '(9334.559 -1477.997));;setting points for window selection
(setq selpt2 '(13249.704 2820.847));;setting points for window selection
(setq ss (ssget "W" selpt1 selpt2 '((0 . "TEXT")(8 . "FILENAME"))));;selecting a single text string on FILENAME layer
(setq vobject (vlax-ename->vla-object (ssname ss 0)))
(setq str (vla-get-textstring vobject));;setting the string to process below
(setq del "_") ;; setting the delimiter for below   ;; this has no effect

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

(setq newlist (mapcar '(lambda (sub) (lm:str->lst sub "-")) (lm:str->lst str "_")))
)

 

If I run through this line by line, copying fromt he code to the command line it works.  If I load the program and execute command "C:ParseBy_Then-"   I get a "too few arguments error"


 

Learn HERE  how to use arguments.

0 Likes
Message 18 of 22

ВeekeeCZ
Consultant
Consultant

My original intention was to use the routine as a subfunction.

 

 

(defun c:MyRoutine ( / ParseBy_then- selpt1 selpt2 ss vobject str lst)
  
    
  (defun ParseBy_then- (str / LM:str->lst)
    
    (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)))
    
    (mapcar '(lambda (sub) (LM:str->lst sub "-")) (LM:str->lst str "_")))


  
  (setq selpt1 '(9334.559 -1477.997))	;;setting points for window selection
  (setq selpt2 '(13249.704 2820.847))	;;setting points for window selection
  
  (if (and (setq ss (ssget "W" selpt1 selpt2 '((0 . "TEXT") (8 . "FILENAME"))))	;;selecting a single text string on FILENAME layer
	   (setq vobject (vlax-ename->vla-object (ssname ss 0)))
	   (setq str (vla-get-textstring vobject)) 				;;setting the string to process below
	   (setq lst (ParseBy_then- str))
	   )
    
    (cond ((= (length lst) 1)
	   (do-a)
	   )
	  
	  ((apply '= lst)
	   (do-b)
	   )
	  
	  (T
	   (do-c)
	   )))
  (princ)
  )

0 Likes
Message 19 of 22

Travis.Biddle
Advocate
Advocate

Perfect, thank you so much!!  I had a feeling the issue was the global/local variables since I could step though manually fine, but for the life of me I couldn't figure it out.  Very much appreciated

0 Likes
Message 20 of 22

ВeekeeCZ
Consultant
Consultant

@Travis.Biddle wrote:

Perfect, thank you so much!!  I had a feeling the issue was the global/local variables since I could step though manually fine, but for the life of me I couldn't figure it out.  Very much appreciated


 

You really should read the link gave you.

 

The correct term is an "argument".

 

(defun name (arg1 arg2  / locvar1 locvar2)    ; if a variable is not listed between locvars, its a global.

 )

 

; arguments are "local" automatically!

 

the above function is called by (name "value-for-arg1" "value-for-arg2")  ;-  by this, arg1 =  "value-for-arg1" , you don't need to use (setq arg1 ...)

 

If you create a command with "C:" prefix, don't use arguments. 

 

0 Likes