Jump to content

Recommended Posts

Posted (edited)

Good day to all!

How to replace only the numbers at the end in the text (mtext).
Select multiple texts and replace the numbers with the same number.
Is there a lisp that allows you to replace only numbers in selected texts?

For example:
Text 1
Text text 1
Text text text 1

MLeader 1

Replace with:

Text 34
Text text 34
Text text text 34

MLeader 34

Is it possible to add MLeaders to the selection?

Thank you in advance...

 

Replace numbers.dwg

Edited by Nikon
Posted

CAN YOU USE THIS

https://www.lee-mac.com/parsenumbers.html

 

;; Parse Numbers  -  Lee Mac
;; Parses a list of numerical values from a supplied string.

(defun LM:parsenumbers ( str )
    (   (lambda ( l )
            (read
                (strcat "("
                    (vl-list->string
                        (mapcar
                           '(lambda ( a b c )
                                (if (or (< 47 b 58)
                                        (and (= 45 b) (< 47 c 58) (not (< 47 a 58)))
                                        (and (= 46 b) (< 47 a 58) (< 47 c 58))
                                    )
                                    b 32
                                )
                            )
                            (cons nil l) l (append (cdr l) '(()))
                        )
                    )
                    ")"
                )
            )
        )
        (vl-string->list str)
    )
)

 

Posted

Nikon

Those are bad examples.

What do you want when it's something defferent from a 1?

What about two ones?

What about two numbers on different places?

 

"Text 1text 1"

"T3322223333665589657ext text"

"Tex44t text text9000"

 

What do you expect there?

Posted (edited)
25 minutes ago, Emmanuel Delay said:

 

"Text 1text 1"

"T3322223333665589657ext text"

"Tex44t text text9000"

 

What do you expect there?

I have text (or MLeader) with the same numbers at the end (1 or 12 or 33...)
I need to replace all the same numbers with other same ones... see the attached .dwg

The numbers are only at the end

Replace numbers.png

Edited by Nikon
Posted

With your exemple seem to do the job.

(defun extractNumbers (str / l rslt)
  (setq
    l
    (mapcar
      '(lambda (x)
        (if (and (> x 44) (< x 58) (/= x 47)) x 32)
      )
      (vl-string->list str)
    )
    l
    (mapcar
      '(lambda (x y)
        (if (not (= x y 32)) x)
      )
      l
      (append (cdr l) '(32))
    )
    l (vl-remove-if-not '(lambda (x) (eq (type x) 'INT) x) l)
    l (mapcar '(lambda (x) (if (not (eq x 32)) x (list nil))) l)
  )
  (eval (read (strcat "(setq rslt (list " (apply 'strcat (mapcar '(lambda (x) (if (not (listp x)) (chr x) " ")) l)) "))")))
)
(defun c:replacenumber ( / ss nb n ename dxf_ent txt old_num old_list)
  (setq ss (ssget '((0 . "*TEXT"))))
  (cond
    (ss
      (initget 1)
      (setq
        nb (getint "\nEnter number to substitue: ")
        nb (vl-string->list (itoa nb))
      )
      (repeat (setq n (sslength ss))
        (setq
          ename (ssname ss (setq n (1- n)))
          dxf_ent (entget ename)
          txt (cdr (assoc 1 dxf_ent))
        )
        (setq
          old_num (vl-string->list (itoa (car (extractNumbers txt))))
          old_list (vl-string->list txt)
        )
        (foreach e old_num (setq old_list (vl-remove e old_list)))
        (entmod (subst (cons 1 (vl-list->string (append old_list nb))) (assoc 1 dxf_ent) dxf_ent))
      )
    )
  )
  (prin1)
)

 

  • Like 1
Posted
5 hours ago, Tsuky said:
(defun c:replacenumber

@Tsuky Thanks a lot!

This code handles text and mtext well.

Is it possible to add MLeader and attributes?

I have similar designs that I copy, modify and change the names with numbers.
I changed 30-40 titles one by one, I caught myself at number 35 and asked for help,
I will need to change 100 or more numbers.
You have helped me a lot!

Posted
Quote

Is it possible to add MLeader and attributes?

Tested briefly ....

(vl-load-com)
(defun extractNumbers (str / l rslt)
  (setq
    l
    (mapcar
      '(lambda (x)
        (if (and (> x 44) (< x 58) (/= x 47)) x 32)
      )
      (vl-string->list str)
    )
    l
    (mapcar
      '(lambda (x y)
        (if (not (= x y 32)) x)
      )
      l
      (append (cdr l) '(32))
    )
    l (vl-remove-if-not '(lambda (x) (eq (type x) 'INT) x) l)
    l (mapcar '(lambda (x) (if (not (eq x 32)) x (list nil))) l)
  )
  (eval (read (strcat "(setq rslt (list " (apply 'strcat (mapcar '(lambda (x) (if (not (listp x)) (chr x) " ")) l)) "))")))
)
(defun c:replacenumber ( / ss nb n ename txt rslt old_num old_list)
  (setq
    ss
    (ssget
      (list
        (cons 0 "*TEXT,MULTILEADER,INSERT")
        (cons 67 (if (eq (getvar "CVPORT") 2) 0 1))
        (cons 410 (if (eq (getvar "CVPORT") 2) "Model" (getvar "CTAB")))
      )
    )
  )
  (cond
    (ss
      (initget 1)
      (setq
        nb (getint "\nEnter number to substitue: ")
        nb (vl-string->list (itoa nb))
      )
      (repeat (setq n (sslength ss))
        (setq
          ename (vlax-ename->vla-object (cadar (ssnamex ss (setq n (1- n)))))
        )
        (cond
          ((vlax-property-available-p ename 'TextString) (setq txt (vlax-get ename 'TextString))
            (cond
              ((eq (type (setq rslt (car (extractNumbers txt)))) 'INT)
                (setq
                  old_num (vl-string->list (itoa rslt))
                  old_list (vl-string->list txt)
                )
                (foreach e old_num (setq old_list (vl-remove e old_list)))
                (vlax-put ename 'TextString (vl-list->string (append old_list nb)))
              )
            )
          )
          (T
            (mapcar 
              '(lambda (att)
                (setq txt (vlax-get-property att 'TextString))
                (cond
                  ((eq (type (setq rslt (car (extractNumbers txt)))) 'INT)
                    (setq
                      old_num (vl-string->list (itoa rslt))
                      old_list (vl-string->list txt)
                    )
                    (foreach e old_num (setq old_list (vl-remove e old_list)))
                    (vlax-put-property att 'TextString (vl-list->string (append old_list nb)))
                  )
                )
              )
              (vlax-invoke ename 'GetAttributes)
            )
          )
        )
      )
    )
  )
  (prin1)
)

 

  • Like 1
Posted
50 minutes ago, Tsuky said:
 (cons 0 "*TEXT,MULTILEADER,INSERT")

@Tsuky Thanks for the quick reaction!
It works well with mleaders. But it doesn't work with attributes.

Posted

Please give me an example drawing so I can identify what is wrong.

Posted (edited)
1 hour ago, Tsuky said:

Please give me an example drawing so I can identify what is wrong.

I have attributes in a dynamic block, I will need to change the numbers in one of them 
(maybe you need to specify an attribute tag to select?)
maybe it will be easier to write a separate code for attributes?

 

GRAPH_F.dwg

Edited by Nikon
Posted

If it was me I'd use something like entsel to grab the text values, then use Lee Macs string to List with a delimitator of space ( " ") to split the string up into part, reverse the list and subs the new value into what is now the first item in the list. Reverse the list again, Lee Macs List to String, and pop that back into the text. Noting that uses a similar method.

 

For attribute blocks, VLA- functions to get and replace the text strings in the attributes rather than entsel

  • Thanks 1
Posted

Has anyone ever written a decent function that extracts all kinds of numeric values from a string?

for example "foo12.3e+6bar" should find 12.3E+6 (12.3 million)

 

What I would like is for the function either to return a list of the numbers along with position and length in the string.

Like "foo36bar12.4test" =>(list  (list 3 2 36) (list 8 4 12.4) )

Or return alternate string / number ... (list "foo" 36 "bar" 12.4 "test")

Posted
50 minutes ago, Tsuky said:

This version ?

replacenumber.lsp

@Tsuky  very, very grateful!
This code performs the task wonderfully!
Now the work will go faster...

Posted (edited)

@BIGAL

Okay, I wrote something.

It seems to work.  It needs some cleanup no doubt

 

It's a way to extract numbers from a string.

 

@Nikon is your problem solved? 

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; @FILE:
;; function  ENFS (for Extract Numbers From String) takes a string and returns a list of numbers in the string
;; the list is (list (list startPosition stringLength string) ... ) for each found number

;; substring, like php substr
(defun substring ( str idx len )
  (substr str (if (< idx 0) (+ 1 (strlen str) idx) (1+ idx)) len)
)


;; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/vba-method-quot-isnumeric-quot-lt-useing-in-vlisp/m-p/793105#M18763
(defun IsNumeric (string)
	(and 
		(lastCharNumeric string)
		(distof string 2)
	)
)

;; requires function substring
(defun lastCharNumeric (str / chrs)
	(setq chrs (vl-string->list str))
	(and
		(> (last chrs) 44) (< (last chrs) 58)
	)
)

(defun c:ENFS ( / str)
	(setq str (getstring "\nString: " T))
	(princ
		(ENFS str)
	)	
	(princ)	
) 

;; ENFS for Extract Numbers From String
(defun ENFS (str /  i concat_num start numbers_data tent_num x         )
	
	(setq concat_num nil)
	(setq start 0)
	
	(setq numbers_data (list))
	
	(setq sure_num "")		;; last sure numeric string
	(setq tent_num "")		;; tentative number.  A string that
	
	(setq i 0)
	(foreach x (setq chrs (vl-string->list str))

		(if (or 
				(and (> x 44) (< x 58)) 			;; 0 to 9
				(= x 43) (= x 45) (= x 46) (= x 101) (= x 69)				;; + - . e E      ;; characters that can possibly be part of a number.  For example 12.54e+6
			)
			(progn							;; numerical
				
				(if  concat_num nil
					(progn
						(setq start i)
						(setq concat_num T)
					)
				)
				
				(setq tent_num (substring str start  (+ 1 (- i start)) ) )
				(if (IsNumeric tent_num)
					(progn
						(setq sure_num tent_num)
						;;(princ tent_num)
					)
				)
				
				;;(princ (chr x))
			)
			;; else: not possibly a character that forms a number.
			;; so if this was not already done, we stop the number concatenation
			(progn
				(setq concat_num nil)
				;;(princ "\n*")
			)

		)
		
		;; if it's the last character, we stop concatenating, so the last number gets added if it's at the end of the string
		(if (= i (- (strlen str) 1) )
			(setq concat_num nil)
		)
		
		;; see if we must add the number to the list
		;; if tent_num
		(if (> (strlen sure_num) 0)
			(if concat_num
				T
				;; concatenating the number has ended, we will add the number to the list
				(progn
					(setq numbers_data (append numbers_data (list
						(list i (strlen sure_num) sure_num)
					)))
					(setq sure_num "")
				)	
			)
		)
		(setq i (+ i 1))
	)
	;;(princ "\n\n")
	;;(princ numbers_data)
	
	;; return list
	numbers_data
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 

Edited by Emmanuel Delay
  • Like 1
Posted
58 minutes ago, Emmanuel Delay said:

 

@Nikon is your problem solved? 

Thanks, the problem is solved. The code Tsuky (replacenumber.lsp) works perfectly.

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