Author Topic: change text in middle of string  (Read 4644 times)

0 Members and 1 Guest are viewing this topic.

andrew_nao

  • Guest
change text in middle of string
« on: April 03, 2012, 11:48:54 AM »
problem:
I have code that adds metric to english feet and inches units. it works when the entity is just numbers.
example -
12'-6" will result in
12'-6" (3810mm) <- good

however if there is text in entity with the numbers its puts the metric at the end
example -
12'-6" dia circle will result in
12'-6" dia circle (3810mm) <- not good

and if there is a fraction in there...

example -
12'-6 1/2" dia circle results in
Select object: ; error: divide by zero <-  :realmad:

goal:
what im after is no matter where in the string 12'-6 1/2" is, i want it to display the metric equivalent right next to it.
so if the string said "this is a 12'-6 1/2" dia circle"
i would like it to say "this is a 12'-6 1/2" (3823mm) dia circle"

for the life of me i just cant figure this out and hope someone can guide me in the right direction.

thanks

code:
please excuse the messy formating.

Code: [Select]

(DEFUN C:test (/)
(DEFUN FTDEC (ASTR / BUF RES C R1)
(SETQ BUF "" RES 0.0)
(WHILE (> (STRLEN ASTR) 0)
(SETQ C (SUBSTR ASTR 1 1) ASTR (SUBSTR ASTR 2))
(COND
((= C "'")
(SETQ RES (* (ATOF BUF) 12.0) BUF "" ASTR (SUBSTR ASTR 2))
)
((= C "/")
(SETQ R1 (ATOF BUF) BUF "")
)
((= C " ")
(SETQ RES (+ RES (ATOF BUF)) BUF "")
)
((/= C (CHR 34))
(SETQ BUF (STRCAT BUF C))
)
)
)
(IF R1
(+ RES (/ R1 (ATOF BUF)))
(+ RES (ATOF BUF))
)
);end while
;
(SETVAR "CMDECHO" 0)
(SETQ DSCL (GETVAR "DIMSCALE"))
(SETQ ENT1 (ENTSEL))
(SETQ ENT2 (ENTGET (CAR ENT1)))
(SETQ ANG1 (ATOF (ANGTOS (CDR (ASSOC 50 ENT2)))))
(SETQ NUM4 (CDR (ASSOC 1 ENT2)))
  (IF (WCMATCH NUM4 "%%*")
(SETQ NUM4 (SUBSTR NUM4 4))
)
(setq Mort (CDR (ASSOC 0 ENT2)))
(SETQ NUM5 (FTDEC NUM4))
(IF (= NUM4 nil) (SETQ NUM4 0))
(SETQ P1 (* num5 25.4))
(IF (= MORT "TEXT")
(SETQ P4 (STRCAT (cdr (assoc 1 ent2))" (" (RTOS P1 2 0) "mm)"))
);END IF
(IF (= ANG1 0) (SETQ SPC (STRCAT "@0,-" (RTOS (* 0.2212 DSCL) 2))))
(IF (= ANG1 90) (SETQ SPC (STRCAT "@" (RTOS (* 0.2212 DSCL) 2) ",0")))
(IF (= ANG1 180) (SETQ SPC (STRCAT "@0," (RTOS (* 0.2212 DSCL) 2))))
(IF (= ANG1 270) (SETQ SPC (STRCAT "@-" (RTOS (* 0.2212 DSCL) 2) ",0")))
(SETVAR "CMDECHO" 1)

(SETQ ent2 (SUBST (CONS 1 P4) (ASSOC 1 ent2) Ent2))
(ENTMOD Ent2)
(PRINC)
)


BlackBox

  • King Gator
  • Posts: 3770
Re: change text in middle of string
« Reply #1 on: April 03, 2012, 12:18:42 PM »
Consider using the position of the first "space" when placing the 'metric' string:

Code - Auto/Visual Lisp: [Select]
  1. (vl-string-position (ascii " ") "12'-6 1/2\" dia circle")
"How we think determines what we do, and what we do determines what we get."

nivuahc

  • Guest
Re: change text in middle of string
« Reply #2 on: April 03, 2012, 02:09:01 PM »
Consider using the position of the first "space" when placing the 'metric' string:

Code - Auto/Visual Lisp: [Select]
  1. (vl-string-position (ascii " ") "12'-6 1/2\" dia circle")

Maybe it's just me, but I see a problem with that method.  :lol:

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: change text in middle of string
« Reply #3 on: April 03, 2012, 03:09:18 PM »
Play with this.
Code: [Select]
(defun c:test (/ num str x idx )
  ;;+++++++++++++++++++++++++++++++
  ;;  convert the text to a number
  ;;+++++++++++++++++++++++++++++++
  (defun txt2num (txt) ; CAB 10/2005
    (cond
      ((distof txt 5))
      ((distof txt 2))
      ((distof txt 1))
      ((distof txt 4))
      ((distof txt 3))
    )
  )
  (setq str "12'-6 1/2\" dia circle")
  (setq idx (strlen str))
  (while (not (numberp (setq x (txt2num (substr str 1 idx)))))
    (setq num x idx (1- idx)))
  (setq newstr (strcat (substr str 1 idx) "(my mm)" (substr str idx)))
 )
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

BlackBox

  • King Gator
  • Posts: 3770
Re: change text in middle of string
« Reply #4 on: April 03, 2012, 03:35:18 PM »
Consider using the position of the first "space" when placing the 'metric' string:

Code - Auto/Visual Lisp: [Select]
  1. (vl-string-position (ascii " ") "12'-6 1/2\" dia circle")

Maybe it's just me, but I see a problem with that method.  :lol:

Doh - Meant the second space, but still. LoL

** Edit - Perhaps this instead:

Code - Auto/Visual Lisp: [Select]
  1. (vl-string-position (ascii "\"") "12'-6 1/2\" dia circle")

Again, it really depends on the consistency of your labels.
« Last Edit: April 03, 2012, 04:05:01 PM by RenderMan »
"How we think determines what we do, and what we do determines what we get."

andrew_nao

  • Guest
Re: change text in middle of string
« Reply #5 on: April 03, 2012, 04:02:49 PM »
Play with this.
Code: [Select]
(defun c:test (/ num str x idx )
  ;;+++++++++++++++++++++++++++++++
  ;;  convert the text to a number
  ;;+++++++++++++++++++++++++++++++
  (defun txt2num (txt) ; CAB 10/2005
    (cond
      ((distof txt 5))
      ((distof txt 2))
      ((distof txt 1))
      ((distof txt 4))
      ((distof txt 3))
    )
  )
  (setq str "12'-6 1/2\" dia circle")
  (setq idx (strlen str))
  (while (not (numberp (setq x (txt2num (substr str 1 idx)))))
    (setq num x idx (1- idx)))
  (setq newstr (strcat (substr str 1 idx) "(my mm)" (substr str idx)))
 )

thanks CAB, this is a good start for me, however if there is any text before the number this is what is returned:

im a little stumped on this one..

Select object: ; error: bad argument value: non-negative: -1

example text line
"there is two (2) 3/4" dia holes"


BlackBox

  • King Gator
  • Posts: 3770
Re: change text in middle of string
« Reply #6 on: April 03, 2012, 04:23:45 PM »
FWIW -

Break Strings to List:
Code - Auto/Visual Lisp: [Select]
  1. (defun BreakStrings->List  (str char / i)
  2.       ;; Example:
  3.       ;; (BreakStrings->List "there is two (2) 3/4\" dia holes" "\"")
  4.       (if (setq i (1+ (vl-string-position (ascii char) str)))
  5.         (list (substr str 1 (setq i (1+ i)))
  6.               (substr str (1+ i) (strlen str)))))
  7.  

Sample output:
Code - Auto/Visual Lisp: [Select]
  1. _$ (BreakStrings->List "there is two (2) 3/4\" dia holes" "\"")
  2. ("there is two (2) 3/4\" " "dia holes")
  3. _$
  4.  

Merge Strings:
Code - Auto/Visual Lisp: [Select]
  1. (defun MergeStrings  (str char str+ / i)
  2.       ;; Example:
  3.       ;; (MergeStrings "there is two (2) 3/4\" dia holes" "\"" "TEST ")
  4.       (if (setq i (1+ (vl-string-position (ascii char) str)))
  5.         (strcat (substr str 1 (setq i (1+ i)))
  6.                 str+
  7.                 (substr str (1+ i) (strlen str)))))
  8.  

Sample ouput:
Code - Auto/Visual Lisp: [Select]
  1. _$ (MergeStrings "there is two (2) 3/4\" dia holes" "\"" "TEST ")
  2. "there is two (2) 3/4\" TEST dia holes"
  3. _$
  4.  

** Edit - This obviously works best when there's a unique character, as is the case in the examples shown. Duplicate characters in the same source string would yield the first character serving as the break/merge point.

HTH
"How we think determines what we do, and what we do determines what we get."

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: change text in middle of string
« Reply #7 on: April 03, 2012, 05:50:59 PM »
Not the most efficient, but it works (it seems  :lmao: )
Code - Auto/Visual Lisp: [Select]
  1. (defun ExtractImperial (str / len n m c res)
  2.   (setq n 0 len (strlen str) res "")
  3.   (while (and (not (wcmatch res "*#',*#\"")) (< n len))
  4.     (while (and (<= (setq n (1+ n)) len) (not (wcmatch (substr str n 1) "[0-9]"))))
  5.     (setq m 0)
  6.     (while (and (<= (+ n (setq m (1+ m))) (1+ len)) (not (wcmatch (substr str n m) "*[~-'0-9/\" ]*"))))
  7.     (setq res (vl-string-trim " /-" (substr str n (1- m))) n (+ n m)))
  8.   (if (wcmatch res "*#',*#\"") res ""))
  9.  
  10. (defun AddMetric (str / imp num)
  11.   (if (and (wcmatch (setq imp (ExtractImperial str)) "*#',*#\"")
  12.            (setq num (distof imp 4)))
  13.     (vl-string-subst (strcat imp " (" (rtos (cvunit num "inch" "mm") 2 0) "mm)") imp str)
  14.     str))

Testing code:
Code: [Select]
_$ (AddMetric "12'-6\"")
"12'-6\" (3810mm)"
_$ (AddMetric "12'-6\" dia circle")
"12'-6\" (3810mm) dia circle"
_$ (AddMetric "this is a 12'-6 1/2\" dia circle")
"this is a 12'-6 1/2\" (3823mm) dia circle"
_$ (AddMetric "circle dia = 12'-6 1/2\"")
"circle dia = 12'-6 1/2\" (3823mm)"
_$ (AddMetric "circle-dia = 12'-6 1/2\"")
"circle-dia = 12'-6 1/2\" (3823mm)"
_$ (AddMetric "circle '/ \"-dia = 12'-6 1/2\"")
"circle '/ \"-dia = 12'-6 1/2\" (3823mm)"
_$ (AddMetric "No. 1 circle '/ \"-dia = 12'-6 1/2\"")
"No. 1 circle '/ \"-dia = 12'-6 1/2\" (3823mm)"
Seems to work for the cases I can think of.

I'd imagine the most efficient way of going at this would be using regular expressions.
« Last Edit: April 03, 2012, 06:12:59 PM by irneb »
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

andrew_nao

  • Guest
Re: change text in middle of string
« Reply #8 on: April 04, 2012, 09:11:30 AM »
FWIW -

Break Strings to List:

yea i thought about that last night.
1-to break it down into a list
2-make sure any other numbers in the same entity are not included if they arent part of the measurement
3- convert the measurement and add to the end of the english measrement
4- build the list back into a string with the conversion

but the difficult part for me is to make it universal so that it covers all the possible scenarios.

i guess i will have to start over with this one