Remove a text character from a text string in Lisp

Remove a text character from a text string in Lisp

Anonymous
Not applicable
11,428 Views
11 Replies
Message 1 of 12

Remove a text character from a text string in Lisp

Anonymous
Not applicable

I found this small lisp routine that allows searching of a dwg for all instances of a specified text string (case sensitive) and replace it with a specified text string:

 

  (setq tss (ssget "X" (list (cons 1 "OLD-NOT WHAT I NEED"))))
  (repeat (sslength tss)
    (setq
      tdata (entget (ssname tss 0))
      tdata (subst (cons 1 "NEW-WHAT I NEED") (assoc 1 tdata) tdata)
    ); end setq
    (entmod tdata)
    (ssdel (ssname tss 0) tss)
  ); end repeat

 

It works great but I need help to write a similar routine that searches for a particular character within all text strings and remove it from those text strings.

To complicate matters, the characters I need to remove from the strings are quote marks ("). I'm not even sure where to begin because, as in the lisp routine above, the quote characters are used by lisp to enclose the old/new strings.

In addition to this, the text strings I need to change are always different like "A" or "XYZ".  So in short, and to use this example, I want the result to be like A or XYZ.

 

I have very few other characters that would need to be removed also, like the pound character (#).

So if i can get the quote one working I can simply copy the routine to handle the pound character also.

These few characters are all that need to change so I will hard code the characters that I want changed.

I do not want the routine to pause for my input until I type in a character, but rather I want it to run uninterrupted.

 

I know this can be done with the find/replace command of AutoCAD; however, I have been tasked with making this a part of a larger lisp routine for standardization.

 

Any help you can provide it greatly appreciated

 

Barry Navarre

Lafayette, Louisiana

 

0 Likes
Accepted solutions (1)
11,429 Views
11 Replies
Replies (11)
Message 2 of 12

Kent1Cooper
Consultant
Consultant

The text content in entity data for a double-quote character is a backslash followed by one, the backslash meaning "the following double-quote character is to be taken literally, and is not defining an end of the string content."  If you look at the entity data of a Text object that shows in the drawing as "A", its content entry will be

 

(1 . "\"A\"")

 

So if that gets set into a variable:

 

(setq test "\"A\"")

 

you can strip the double-quotes out of it this way:

 

(while

  (wcmatch test "*\"*") ; does the string still contain any double-quote characters?

  (setq test (vl-string-subst "" "\"" test)) ; replace the first one it finds with nothing

)

 

which in that case returns "A", which as string content when applied to the Text object will of course appear in the drawing as just A.

 

I will assume you know enough to be able to extract the content from existing Text/Mtext objects and process it in that way, to get a value to put in place of your "NEW-WHAT I NEED", but write back if you need more help.

Kent Cooper, AIA
Message 3 of 12

martti.halminen
Collaborator
Collaborator

To expand on the previous, the backslash \ is the escape character for anything in Lisp strings, not just the double quote.

 

That is the reason you need to write Windows file paths in Lisp with slashes or double backslashes: "C:\temp\" would be read as "C:temp and whatever exists before the next doublequote", so use "C:/temp/" or "C:\\Temp\\".

 

- To further the confusion, that is just for reading the strings. The function using a string may impose further semantics, for example WCMATCH uses  a backquote ` as its escape character.

 

-- 

0 Likes
Message 4 of 12

Anonymous
Not applicable

Kent and Martti,

Thank you for your reply and bit of code, and I apologize for my late reply as I was out of office.

I'm afraid Kent, your assumtion would be incorrect as I am very much a novice on things lisp.

I have cobbled simple things together from found routines and amaze myself when they sometimes work.

 

This one searching text strings and deleting certain characters is way above my expertise.

I do understand your explanation of the backslash meaning "this is not the end of the string content", and this is duly noted..

However, now that this would make the selection set, how do I now change the text to get rid of the quote characters?

 

But wait, before you explain, there's more!

I probably did not explain my intentions in the original post well enough, and this will likely change your advice.

I'm not looking for specific strings like "A" but rather I want the routine to get rid of every quote character ( " ) and every pound character ( # ) from every piece of text in the drawing, regardless of the characters in the string that accompany them.  Thus leaving the string with only the accompanying characters wether they be A or Z, or 1 or 10, etc.

Hopefully this little revelation might even simplify the lisp and any futher advice you might have.

 

Thanks for your help

0 Likes
Message 5 of 12

Kent1Cooper
Consultant
Consultant
Accepted solution

@Anonymous wrote:

.... I want the routine to get rid of every quote character ( " ) and every pound character ( # ) from every piece of text in the drawing, regardless ....


Try this [rather basic, very lightly tested]:

 

 

(defun C:SQP (/ ss n tobj); = Strip Quotation marks and Pound signs
  (while (setq ss (ssget "_X" '((0 . "*TEXT") (1 . "*\"*,*`#*"))))
    (repeat (setq n (sslength ss))
      (vla-put-TextString
        (setq tobj (vlax-ename->vla-object (ssname ss (setq n (1- n)))))
        (vl-string-subst "" "\"" (vla-get-TextString tobj)); replace evil " with nothing
      )
      (vla-put-TextString
        tobj
        (vl-string-subst "" "#" (vla-get-TextString tobj)); replace evil # with nothing
      )
    ); repeat
  ); while
); defun

It has to go back and check again [the (while) part] because (vl-string-subst) only replaces the first instance it finds of the "old" character(s).

 

Kent Cooper, AIA
Message 6 of 12

zph
Collaborator
Collaborator

I just tried the FIND command and using the replace function it worked perfectly to replace any character I wanted with an empty space.  You may need to uncheck the 'Use wildcards' search function though.

 

All I'd need to do is repeat this operation for each character you want replace for each piece of text and mtext in the drawing.

 

No big deal really, but I don't have time to write it today.  If you don't have the needed code by tomorrow I can give it a go tomorrow.

 

Do you want to the keep the empty spaces or take them away (in this sense making the text string shorter)?

0 Likes
Message 7 of 12

Kent1Cooper
Consultant
Consultant

@zph wrote:

I just tried the FIND command and using the replace function it worked perfectly to replace any character I wanted with an empty space.  ....


Why didn't I think of that?  But given that approach, I find that I can replace whatever character I want with nothing directly [just leave the "Replace with:" slot empty, and pick on "Replace All"] -- no need to replace them with spaces and then get rid of those later.

Kent Cooper, AIA
Message 8 of 12

zph
Collaborator
Collaborator
I didn't realize that I could actually leave the 'replace' field empty and it would replace with nothing.

Thanks, Kent! ....learn something new everyday 🙂
0 Likes
Message 9 of 12

Anonymous
Not applicable

Thanks Kent this is exactly what I was looking for.

This is a great help.

0 Likes
Message 10 of 12

Anonymous
Not applicable

Thanks for the input ZPH.

I did know the replace function did this (and removed the blanks), but I needed this as part of a larger lisp routine that does many other things.

You know how everybody wants an EASY button and everything is done for them in one simle click.

Had I been able to call the find command in a lisp, this function I needed would have been a snap.

Unfortunately, it doesnt work that way.

 

I'm gald you could also benefit from this subject... and give Kent's routine a try, it's works great.

 

0 Likes
Message 11 of 12

Anonymous
Not applicable

Thanks a lot @Anonymous , I found what I was looking for.

0 Likes
Message 12 of 12

Anonymous
Not applicable

Appreciated..! But I guess there's already a built-in function in AutoCAD which does the pretty much same job, if I got it right, what claimed for the given above Lisp to be doing. Just use the command FIND and the "Find and Replace" dialogue box will appear for the user inputs.  

 

PS: Tested the above command on AutoCAD 2019.

0 Likes