Jump to content

Lisp to remove spaces in a string


sadhu

Recommended Posts

(defun AT:NoSpaces (str / str)
 ;; Remove all spaces from string
 ;; str - valid string
 ;; Alan J. Thompson, 03.20.09
 (if (eq (type str) 'STR)
   (while (vl-string-search " " str)
     (setq str (vl-string-subst "" " " str))
   )
 )
)

Link to comment
Share on other sites

I'm looking for a lisp routine that removes spaces in a string.

 

" D-2 TV 2 " becomes "D-2TV2"

 

Thanks.

 

My 2 cents

(defun vl-remove-blanks (string)
(vl-list->string
 (vl-remove
   32
 (vl-string->list string )))
 )

 

~'J'~

Link to comment
Share on other sites

You know, when I wrote the above, I considered that way, but abandoned it because I figured it would be a lot slower. I wish I would have written both and benchmarked them. Converting to/from a list is A LOT faster.

Link to comment
Share on other sites

That will show me to post something I wrote a year ago and not make an attempt at writing something better.

Link to comment
Share on other sites

Elapsed milliseconds / relative speed for 4096 iteration(s):
   (VL-REMOVE-BLANKS S)......1579 / 43.11 <fastest>
   (AT:NOSPACES S)..........29656 / 2.3
   (LM:REMOVESPACES S)......68078 / 1 <slowest>

Used on a string with 2000 characters.

Link to comment
Share on other sites

2000 is a lot of characters - "my strings" have 20 at most. Your benchmark suggests that I choose

 

(defun vl-remove-blanks (string)
(vl-list->string
 (vl-remove
   32
 (vl-string->list string )))
 )

Thanks to all of you.:)

Link to comment
Share on other sites

  • 3 years later...

Hey, can someone help me briefly, how would I use that function on each item in a list , and create a new list of the new items (spaces removed)

I know it'd be mapcar....

 

!VALLIST
(("      " "     ") ("      " "     ") ("      " "     ") ("123" "FT") ("123" 
"FT") ("123" "FT") ("123" "FT") ("123" "FT") ("272" "FT") ("661" "FT") ("123" 
"FT") ("311" "FT") ("51" "FT") ("28" "FT") ("161" "FT") ("69" "FT") ("82" "FT") 
("312" "TI") ("612" "FQ") ("      22" "FE") ("      12" "FT") ("312" "TI") 
("612" "FQ") ("      22" "FE") ("      12" "FT") ("312" "TI") ("612" "FQ") ("   
  22" "FE") ("      12" "FT") ("123" "FT") ("123" "FT") ("123" "FT") ("123" 
"FT") ("123" "FT") ("272" "FT") ("661" "FT") ("123" "FT") ("311" "FT") ("51" 
"FT") ("28" "FT") ("161" "FT") ("69" "FT") ("82" "FT") ("312" "TI") ("612" 
"FQ") ("      22" "FE") ("      12" "FT") ("312" "TI") ("612" "FQ") ("      22" 
"FE") ("      12" "FT") ("312" "TI") ("612" "FQ") ("      22" "FE") ("      12" 
"FT") ("18" "TT") ("47" "FE") ("61" "FT") ("22" "TI") ("15" "TE") ("272" "FQ") 
("18" "TE") ("123" "TT") ("22" "FQI") ("22" "FQ") ("18" "FE") ("92" "PI") ("12" 
"PP") ("92" "TI") ("06" "PP") ("612" "FQ") ("      22" "FE") ("      12" "FT") 
("312" "TI") ("612" "FQ") ("18" "TT") ("11" "TI") ("312" "TI") ("612" "FQ") ("  
   22" "FE") ("      12" "FT"))

 

So, i'd need to pass each item in succession to the function as an argument.

(setq c 0)
(while (< c (length vallist))
(setq newitem (lm:removespaces (nth 0 vallist)))
(setq c (1+ c))
);while

 

Seems to work, but it gives an error...

 

; error: bad argument type: stringp ("      " "     ")

and you can see that the first item is just all spaces, so how would I handle this ?

And then how would I reconstruct the list, with all of the spaces removed in the items now?

I know I'm close and I'll keep tinkering, just hoping for some assistance.

Link to comment
Share on other sites

Thanks Pbe. Now if only I knew to construct this logic without assistance :/

Thanks anyways though! I figured lambda and mapcar would be the best way to handle such a list

Link to comment
Share on other sites

Thanks Pbe.Now if only I knew to construct this logic without assistance

 

Why of course you do, I think you just ran out of tracks is all. Most important is you try

 

...Thanks anyways though! I figured lambda and mapcar would be the best way to handle such a list

 

If you are meaning help with your posted code

 

(setq c 0)
(while (< c (length vallist));<-- suggest not to use while, i dont think you need to set a condition just process the whole list , try foreach or repeat
(setq newitem (lm:removespaces (nth 0 vallist))) ;<-- in here, you are trying to process a "list" whilst the required argument for the routine is a "string"
(setq c (1+ c))
);while

 

Try this way [without the use of mapcar/lambda]

 

(defun demo1 (lst_ / a newitem)
 (setq c (length lst_))
 (foreach lst (reverse lst_)
   (foreach itm (reverse lst)
     (setq a (cons (lm:removespaces itm) a))
   )
   (setq newitem (cons a newitem)
  a	  nil
   )
 )
 newitem
)

 

or

 

(defun demo2 (lst_ / a c newitem)
 (repeat (setq c (length lst_))
   (foreach itm (reverse (nth (setq c (1- c)) lst_))
     (setq a (cons (lm:removespaces itm) a))
   )
   (setq newitem (cons a newitem)
  a	  nil
   )
 ) newitem
)

 

HTH

Link to comment
Share on other sites

  • 4 years later...

Here's a function I'm using on a script I'm working on. Another 2 cents into the pot.

 

;;----------------------------------------------------------------------;;
;; REMOVES INVALID ACAD CHARACTERS, EXTRA WHITESPACE, LEADING + TRAILING WHITESPACE CHARACTERS
;; by 3dwannab 21.09.18
;; Usage: (_3dwannab_RemoveSnvalidwithExtraWhiteSpaceChars "  a messed   |  up string goes, : here  ")
;; Returns: "a messed up string goes here"

(defun _3dwannab_RemoveSnvalidwithExtraWhiteSpaceChars ( str / regex )
	(setq regex (vlax-create-object "Vbscript.RegExp"))
	(vlax-put-property regex "Global" 1)
	(vlax-put-property regex "Pattern" "[<>\/\\\"\:\?\*\|\,\=`\;]")
	(setq str (vlax-invoke-method regex "Replace" str (strcat "")))
	(vlax-put-property regex "Pattern" "\\s+")
	(setq str (vlax-invoke-method regex "Replace" str (strcat " ")))
	(vlax-put-property regex "Pattern" "^\\s+|\\s+$")
	(setq str (vlax-invoke-method regex "Replace" str (strcat "")))
	(vlax-release-object regex)
	str
	)

 

To just remove all whitespace characters including leading and trailing use.

(defun _3dwannab_RemoveAllWhiteSpaceChars ( str / regex )
	(setq regex (vlax-create-object "Vbscript.RegExp"))
	(vlax-put-property regex "Global" 1)
	(vlax-put-property regex "Pattern" "\\s*")
	(setq str (vlax-invoke-method regex "Replace" str (strcat "")))
	(vlax-release-object regex)
	str
	)

 

 

 

Edited by 3dwannab
Added add. code
Link to comment
Share on other sites

3dwannab,

Obtaining and releasing objects that are external to ACAD is a rather slow approach...

If you decide to stick with regex,  then I'd advise you to modify the subfunction to accept a list of strings as argument,

so you could obtain once the regex object, process all the strings and then release it.

Also you might occur on some problems with formatted mtexts, since their content may look something like this:

Quote

"{\\fArial|b0|i1|c204|p34;\\C2;s\\fArial|b1|i1|c204|p34;t\\L\\C1;ri\\fArial|b1|i0|c204|p34;\\C4;n\\fArial|b0|i0|c204|p34;g}"

 

Link to comment
Share on other sites

another $0.02, hiccup - overrides strcase

(read (strcat "(" (vl-string-translate "|:," "   " "  a messed   |  up string goes, : here  ")")") )
Quote

 (A MESSED UP STRING GOES HERE) 

 

p/s:  off topic regEx - how about removing  previous forum Tags mass? eg: [ color ] ,  [ B ] , etc..

Link to comment
Share on other sites

4 hours ago, Grrr said:

3dwannab,

Obtaining and releasing objects that are external to ACAD is a rather slow approach...

If you decide to stick with regex,  then I'd advise you to modify the subfunction to accept a list of strings as argument,

so you could obtain once the regex object, process all the strings and then release it.

Also you might occur on some problems with formatted mtexts, since their content may look something like this:

 

In my script I am also using Lee Macs unformat but for the propose of this thread I thought that removing invalid characters and showing a regular expression method would also be useful as I am quite familiar with it. What do you mean list of strings. The lisp I'm working on atm only parses one string and not a list. It's a Rename block with selected text routine. An edit of Alan Js Rename block routine I had from away back. 

 

43 minutes ago, hanhphuc said:

another $0.02, hiccup - overrides strcase


(read (strcat "(" (vl-string-translate "|:," "   " "  a messed   |  up string goes, : here  ")")") )

 

p/s:  off topic regEx - how about removing  previous forum Tags mass? eg: [ color ] ,  [ B ] , etc..

Simple:

To match [ colour ] or [ B ] you could use. But I would need more concrete examples to ensure the proper syntax. 

\[\s*[^\]]{1,6}\s*\]

 

Edited by 3dwannab
Link to comment
Share on other sites

  • 4 months later...

Hello to all!

I have a list:

(("Fax") ("HP LaserJet MFP M725 PCL 6") ("Microsoft Print to PDF") ("Microsoft XPS Document Writer") ("NEZH-HP725-02 (HP LaserJet MFP M725)"))

how do i get a list of this type:

("Fax" "HP LaserJet MFP M725 PCL 6" "Microsoft Print to PDF" "Microsoft XPS Document Writer" "NEZH-HP725-02 (HP LaserJet MFP M725)")

and then do the following (for example):

(setq a "Fax"
      aa "HP LaserJet MFP M725 PCL 6"
      aaa "Microsoft Print to PDF"
      aaaa "Microsoft XPS Document Writer"
      aaaaa "NEZH-HP725-02 (HP LaserJet MFP M725)"
)

I want to assign a variable to each printer in the list.

I will be grateful to everyone who will help.

 

Link to comment
Share on other sites

_$ (apply 'append '(("Fax") ("HP LaserJet MFP M725 PCL 6") ("Microsoft Print to PDF") ("Microsoft XPS Document Writer") ("NEZH-HP725-02 (HP LaserJet MFP M725)")))
("Fax" "HP LaserJet MFP M725 PCL 6" "Microsoft Print to PDF" "Microsoft XPS Document Writer" "NEZH-HP725-02 (HP LaserJet MFP M725)")

I would strongly advise against assigning each element of a list to a separate variable in favour of manipulating the list using the wealth of list functions available in AutoLISP, but if you really must:

_$ (setq l (apply 'append '(("Fax?") ("HP LaserJet MFP M725 PCL 6") ("Microsoft Print to PDF") ("Microsoft XPS Document Writer") ("NEZH-HP725-02 (HP LaserJet MFP M725)"))))
("Fax?" "HP LaserJet MFP M725 PCL 6" "Microsoft Print to PDF" "Microsoft XPS Document Writer" "NEZH-HP725-02 (HP LaserJet MFP M725)")
_$ (setq s "a")
"a"
_$ (foreach x l (set (read s) x) (setq s (strcat s "a")))
"aaaaaa"
_$ a
"Fax?"
_$ aa
"HP LaserJet MFP M725 PCL 6"
_$ aaa
"Microsoft Print to PDF"
_$ aaaa
"Microsoft XPS Document Writer"
_$ aaaaa
"NEZH-HP725-02 (HP LaserJet MFP M725)"

 

Edited by Lee Mac
  • Like 1
Link to comment
Share on other sites

2 hours ago, Lee Mac said:

_$ (apply 'append '(("Fax") ("HP LaserJet MFP M725 PCL 6") ("Microsoft Print to PDF") ("Microsoft XPS Document Writer") ("NEZH-HP725-02 (HP LaserJet MFP M725)")))
("Fax" "HP LaserJet MFP M725 PCL 6" "Microsoft Print to PDF" "Microsoft XPS Document Writer" "NEZH-HP725-02 (HP LaserJet MFP M725)")

I would strongly advise against assigning each element of a list to a separate variable in favour of manipulating the list using the wealth of list functions available in AutoLISP, but if you really must:


_$ (setq l (apply 'append '(("Fax?") ("HP LaserJet MFP M725 PCL 6") ("Microsoft Print to PDF") ("Microsoft XPS Document Writer") ("NEZH-HP725-02 (HP LaserJet MFP M725)"))))
("Fax?" "HP LaserJet MFP M725 PCL 6" "Microsoft Print to PDF" "Microsoft XPS Document Writer" "NEZH-HP725-02 (HP LaserJet MFP M725)")
_$ (setq s "a")
"a"
_$ (foreach x l (set (read s) x) (setq s (strcat s "a")))
"aaaaaa"
_$ a
"Fax?"
_$ aa
"HP LaserJet MFP M725 PCL 6"
_$ aaa
"Microsoft Print to PDF"
_$ aaaa
"Microsoft XPS Document Writer"
_$ aaaaa
"NEZH-HP725-02 (HP LaserJet MFP M725)"

 

 

Thank you very much Lee Mac, that's what I need. And I will definitely remember your words "I would strongly advise against assigning each element of a list to a separate variable".

 

Link to comment
Share on other sites

The choice would be better through a dcl for choosing you could use Lee's listbox dcl or a button dcl.

 

These posts are not really releative to the original post you would have been better starting a new one in the lisp section.

Link to comment
Share on other sites

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