Nikon Posted October 16 Posted October 16 (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 October 16 by Nikon Quote
hosneyalaa Posted October 16 Posted October 16 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) ) ) Quote
Emmanuel Delay Posted October 16 Posted October 16 @ 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? Quote
Nikon Posted October 16 Author Posted October 16 (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 Edited October 16 by Nikon Quote
Tsuky Posted October 17 Posted October 17 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) ) 1 Quote
Nikon Posted October 17 Author Posted October 17 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! Quote
Tsuky Posted October 17 Posted October 17 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) ) 1 Quote
Nikon Posted October 17 Author Posted October 17 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. Quote
Tsuky Posted October 17 Posted October 17 Please give me an example drawing so I can identify what is wrong. Quote
Nikon Posted October 17 Author Posted October 17 (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 October 17 by Nikon Quote
Steven P Posted October 17 Posted October 17 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 1 Quote
Emmanuel Delay Posted October 17 Posted October 17 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") Quote
Nikon Posted October 17 Author Posted October 17 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... Quote
BIGAL Posted October 17 Posted October 17 @Emmanuel Delay over at Theswamp, AutoLisp (Vanilla/Visual) is a sub forum "Challenges" its a good place to put this type of question as I expect some form of mapcar expression to solve. https://www.theswamp.org/index.php?board=2.0 Quote
Emmanuel Delay Posted October 18 Posted October 18 (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 October 18 by Emmanuel Delay 1 Quote
Nikon Posted October 18 Author Posted October 18 58 minutes ago, Emmanuel Delay said: @Nikon is your problem solved? Thanks, the problem is solved. The code Tsuky (replacenumber.lsp) works perfectly. Quote
Recommended Posts
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.