Emmanuel Delay Posted December 17, 2014 Share Posted December 17, 2014 (edited) Hi, I need to escape double quote characters. I read attributes, I write the values to file. Those values need to be escaped in the file. ---- So, what I need should look somewhat like this, only this doesn't work: (princ (replace "\"" "\\\"" attribute_value)) ;; [url]http://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/using-vl-string-subst-to-do-a-find-and-replace-in-external-file/td-p/3732910[/url] (defun replace (newstr oldstr str / localstr) (setq localstr str) (while (vl-string-search oldstr localstr) (setq localstr (vl-string-subst newstr oldstr localstr)) (replace newstr oldstr localstr) ) localstr ) I can't be the first one to need this. Edited December 17, 2014 by Emmanuel Delay Quote Link to comment Share on other sites More sharing options...
Tharwat Posted December 17, 2014 Share Posted December 17, 2014 Maybe the function READ is what you are after ? Quote Link to comment Share on other sites More sharing options...
Emmanuel Delay Posted December 17, 2014 Author Share Posted December 17, 2014 Thanks, but that's not it. It's kind of the reverse that I need. So, I have a block with an attribute (tag = TFT), the value is 32" (as in 32 inch). I read the blocks and write the data to file. This is what I find in my text file: ("TFT" "32"") I need this to be in my text file: ("TFT" "32\"") Quote Link to comment Share on other sites More sharing options...
Tharwat Posted December 17, 2014 Share Posted December 17, 2014 Try it like this and let me know . (if (wcmatch (setq st "32\"") "*\"") (strcat (substr st 1 (1- (strlen st))) (chr 92) (chr 34)) ) Quote Link to comment Share on other sites More sharing options...
SLW210 Posted December 17, 2014 Share Posted December 17, 2014 Please read the Code Posting Guidelines and edit your post to include the Code in Code Tags. Quote Link to comment Share on other sites More sharing options...
Emmanuel Delay Posted December 17, 2014 Author Share Posted December 17, 2014 Try it like this and let me know . (if (wcmatch (setq st "32\"") "*\"") (strcat (substr st 1 (1- (strlen st))) (chr 92) (chr 34)) ) Okay, but I just gave you an example. It won't always be formatted that way (not always at the end of the string, not always 32). It needs to replace any double quote, anywhere. This should be just a simple string replace. I don't understand why this could be this hard Quote Link to comment Share on other sites More sharing options...
Tharwat Posted December 17, 2014 Share Posted December 17, 2014 Okay, but I just gave you an example. And I am also just gave you an example Much more easier if you are interested . (defun _add:slash (st) (if (wcmatch st "*\"") (strcat (substr st 1 (1- (strlen st))) (chr 92) (chr 34)) ) ) Usage of the function . (_add:slash "32\"") Quote Link to comment Share on other sites More sharing options...
Emmanuel Delay Posted December 17, 2014 Author Share Posted December 17, 2014 The way I read your function: - it looks for strings ending on "; - then replaces that by the string except the last character. - then it adds \" to the string. ------ Any way, I still don't have a \ in my file. wcmatch never returns true, apparently. (I put a princ within your function (I added progn), for debugging; nothing is printed Maybe it's required to search the " differently Quote Link to comment Share on other sites More sharing options...
Tharwat Posted December 17, 2014 Share Posted December 17, 2014 The function that I posted earlier works well , anyway show me your codes to check them out . Quote Link to comment Share on other sites More sharing options...
Emmanuel Delay Posted December 17, 2014 Author Share Posted December 17, 2014 I'll get back on it tomorrow. I'll make a minimal version of the script, with a minimal version dwg attachment. Maybe the problem is somewhere earlier in the code; some function that converts/filters/... something, or so. Quote Link to comment Share on other sites More sharing options...
Emmanuel Delay Posted December 18, 2014 Author Share Posted December 18, 2014 Okay, so what I'm interested in, is the last but one function: escape. I added a dwg with a few blocks with attributes. The command is BLOCKS (I like to write the client-accessible function as the last function) This exports the data to "block_export.txt", in the same folder as the dwg (so please don't use this on an unsaved drawing ) What's required: every double quote in the value must be escaped in the .txt file, so that it parses as lisp data (vl-load-com) (defun blocks ( / iterations i block attString content_string) ;; select blocks (all blocks in the dwg) (setq blocks (ssget "X" (list '(0 . "INSERT") )) iterations (sslength blocks) ;; number of iterations i 0 block nil content_string "" ;; this is the variable containing the content we will save to file ) (repeat iterations ;; loop over blocks (setq block (ssname blocks i)) ;; attributes (setq attString "") (foreach att (vlax-invoke (vlax-ename->vla-object block) 'GetAttributes) (setq attVal (vla-get-TextString att)) (setq tag (vla-get-TagString att)) (setq attVal (escape attVal)) (setq attString (strcat attString "(\"" tag "\" \"" attval "\") ")) ) (setq content_string (strcat content_string "(" attString ")\n" )) (setq i (+ 1 i)) ) ;; this prints the contents to file. The file is "block_export.txt" , in the same folder as the dwg. ;; Notice: save the dwg before using this (file_put_contents (strcat (getvar 'dwgprefix) "block_export.txt") content_string) ) ;; http://forums.autodesk.com/t5/visual...e/td-p/3732910 (defun replace (newstr oldstr str / localstr) (setq localstr str) (while (vl-string-search oldstr localstr) (setq localstr (vl-string-subst newstr oldstr localstr)) (replace newstr oldstr localstr) ) localstr ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; file IO. ;; made to look like the php-functions file_put_contents & file_get_contents ;; (Not sure where I found these and how much of it I wrote my self) ;; saves a string to file (defun file_put_contents (file_name content / result f) (setq result T) (if (setq f (open file_name "w")) (progn (write-line content f) (close f) ) (progn (setq result NIL) ) ) result ) ;; read file as string (defun file_get_contents (file_name / content) (setq content "") (if(setq fp (open file_name "r")) ; file pointer (progn (while (setq txtLine(read-line fp)) (setq content (strcat content "\n" txtLine)) ) (close fp) content ; return content ) (progn NIL ; return false ) ) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun _add:slash (st) (if (wcmatch st "*\"") (strcat (substr st 1 (1- (strlen st))) (chr 92) (chr 34)) ) st ) (defun escape(str / ) ;;(replace "\"" "\\\"" str) (_add:slash str) ) (defun c:blocks ( / ) (blocks) (princ) ) Notice: - function replace is not used right now. - file_get_contents is not used at all; but since I provide file_put_contents, I can provide file_get_contents as well. Drawing2.dwg Quote Link to comment Share on other sites More sharing options...
Tharwat Posted December 18, 2014 Share Posted December 18, 2014 Try this and let me know . (defun c:test (/ _add:slash ss i block l f o) ;; Tharwat 18.12.2014 ;; (defun _add:slash (st) (if (wcmatch st "*\"") (setq st (strcat (substr st 1 (1- (strlen st))) (chr 92) (chr 34)) ) st ) st ) (if (setq ss (ssget "_X" '((0 . "INSERT")))) (progn (setq f (strcat (getvar 'dwgprefix) "block_export22.txt") o (open f "w") ) (repeat (setq i (sslength ss)) (foreach x (vlax-invoke (vlax-ename->vla-object (ssname ss (setq i (1- i)))) 'getattributes ) (setq l (cons (strcat "(" (chr 34) (vla-get-tagstring x) (chr 34) " " (chr 34) (_add:slash (vla-get-textstring x)) (chr 34) ")" ) l ) ) ) (write-line (vl-princ-to-string l) o) (setq l nil) ) (close o) ) ) (princ) )(vl-load-com) Quote Link to comment Share on other sites More sharing options...
Emmanuel Delay Posted December 18, 2014 Author Share Posted December 18, 2014 It works for the attributes where " is the last character; thanks. It still doesn't work when the " is somewhere in the middle of the string. But I'm pretty sure I can figure it out from here on. Quote Link to comment Share on other sites More sharing options...
Tharwat Posted December 18, 2014 Share Posted December 18, 2014 It works for the attributes where " is the last character; thanks. Very good , I am happy to hear that . It still doesn't work when the " is somewhere in the middle of the string. But I'm pretty sure I can figure it out from here on. Good luck and don't hesitate to ask if you stuck with any . NOTE: I changed the name of the txt file just for testing and forgot to return it back as it was , so just remove the two 2 numbers from the title . Regards . Quote Link to comment Share on other sites More sharing options...
Tharwat Posted December 18, 2014 Share Posted December 18, 2014 By the way , it is better to add the filter (66 . 1) to include the attributed blocks only in the selection set . Quote Link to comment Share on other sites More sharing options...
Emmanuel Delay Posted December 19, 2014 Author Share Posted December 19, 2014 Yes, I know, but I also need blocks without attributes. As I said, this is a short version of the code, the whole program does a few extra things. Quote Link to comment Share on other sites More sharing options...
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.