Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

String to list...

19 REPLIES 19
Reply
Message 1 of 20
brandzo
5486 Views, 19 Replies

String to list...

Hi all,

 

After a hours and hours of searching, I still can't figure out how to convert a string

 

"(66 50207.267 69778.178 67.092)"

 

into a list

 

(66 50207.267 69778.178 67.092)

 

Seems that if I use (read (strcat... function, it truncates decimal places. Also, delimiter can be space(s), as well as tab(s) or comma(s).

 

Any help would be greatly appreciated.

 

Brandzo

19 REPLIES 19
Message 2 of 20
pbejse
in reply to: brandzo

(read (eval "(66 50207.267 69778.178 67.092)"))

Message 3 of 20
brandzo
in reply to: pbejse

No luck, unfortunately, again the numbers are truncated (see below):

 

Command: (read (eval "(66 50207.267 69778.178 67.092)"))
gives:
(66 50207.3 69778.2 67.092)
I think I should not use READ function. Any other suggestion?

 

Message 4 of 20
Kent1Cooper
in reply to: pbejse


@pbejse wrote:

(read (eval "(66 50207.267 69778.178 67.092)"))


That also truncates decimal places for the longer numbers, as did the shorter one that I had tried:

(read "(66 50207.267 69778.178 67.092)")

 

Both return

(66 50207.3 69778.2 67.092)

 

They make a real list, and they're actually numbers, but I haven't found a way to get the decimal places to stick around, either.

Kent Cooper, AIA
Message 5 of 20
pbejse
in reply to: Kent1Cooper

try this

 

(defun ConvertList  (lst)
      (read (strcat "("
                    (vl-list->string
                          (vl-remove-if
                                '(lambda (x)
                                       (or
                                             (= x 40)
                                             (= x 41)))
                                (vl-string->list
                                      (vl-princ-to-string lst))))
                    ")")
            )
      )

 
(ConvertList "(66 50207.267 69778.178 67.092)")


(66 50207.3 69778.2 67.092)

 

 EDIT:Crap! its the same thing... bummer

 

Message 6 of 20
Kent1Cooper
in reply to: brandzo


@brandzo wrote:

....I think I should not use READ function. Any other suggestion?

 


I don't think (read) itself is what the problem is.  I tried this, in an effort to force it to look at substrings individually without (read):

 

(defun StringToListNS (str / lst)

; = convert list-format String To List when contents are Numbers, Space-delimited
  (setq str (vl-string-trim "()" str))
  (while (wcmatch str "* *")
    (setq lst
      (append
        lst
        (list (atof (substr str 1 (vl-string-position 32 str))))
          ; text prior to first space
      ); end append
    ); end setq
    (setq str (substr str (+ (vl-string-position 32 str) 2)))
      ; text from after first space to end
  ); end while
  (setq lst (append lst (list (atof str)))); remaining text after last space
  lst

But it returns the same truncated values for longer decimal-numerical strings, in addition to [as I knew it would] converting any integers to real numbers.  The cause of that, in this case, seems to be in (atof):

 

Command: (atof "12343.3456")
12343.3
 

Help about (atof) and (read) doesn't suggest anything to explain it, that I could see.  I haven't searched the Discussion Group for any clues about this, but try that.

Kent Cooper, AIA
Message 7 of 20
pbejse
in reply to: brandzo

although its showing you this

 

(66.0 50207.3 69778.2 67.092)

 

using it mathematically will still give you the correct result

 

(+ (cadr (read (eval "(66 50207.267 69778.178 67.092)"))) 52.36) 2 3)

 

50259.6

 

(rtos  (+ (cadr (read (eval "(66 50207.267 69778.178 67.092)"))) 52.36) 2 3)

 

"50259.627"

 

so the question is .does it really matter what you see on the screen? it will give you the correct result anyway right?

 

 no need for eval really.. (my bad)

 

(rtos  (+ (cadr (read "(66 50207.267 69778.178 67.092)")) 52.36) 2 3)

Message 8 of 20
Kent1Cooper
in reply to: brandzo


@brandzo wrote:

.... it truncates decimal places. ....


Well, duh on all of us....  It's only truncating them in display:

 

Command: (setq test (read "(66 50207.267 69778.178 67.092)"))
(66 50207.3 69778.2 67.092)

 

Command: (- (cadr test) 50207.2); check for further decimal places in second number
0.067

 

In other words, the second number in the list really does contain the .267 decimal component, though it doesn't show it that way when the list is printed out.

Kent Cooper, AIA
Message 9 of 20
pbejse
in reply to: Kent1Cooper

exactly!!!

 

 

Message 10 of 20
brandzo
in reply to: brandzo

Thank you guys very much for your time and effort!

 

Cheers,

 

Brandzo

Message 11 of 20
DRossger
in reply to: brandzo

Anybody know how can I convert a string in a list ?

"132 LINE 15.23" -> (132 LINE 15.23)

Message 12 of 20
DRossger
in reply to: brandzo

?

Message 13 of 20
pbejse
in reply to: DRossger

(read (strcat "(" "132 LINE 15.23" ")"))

 (132 LINE 15.23)

 

(defun c:listme  (str)
            (read (strcat "(" str ")"))
            )

 (listme "132 LINE 15.23")

(132 LINE 15.23)

Message 14 of 20

Maybe you need this result:

(ALE_AlphaNumString2List "132 LINE 15.23" " ")
(132 "LINE" 15.23)  >>> "LINE" as string

 

; Marc'Antonio Alessi, Italy - http://alessi.xoom.it/alessi
;
; Function: ALE_AlphaNumString2List
;
; Version 1.11 - 27/04/2005
;
; Description:
;   convert a "alphanumeric" string into a list
;
; Arguments:
;   InpStr = string [STR] with texts and numbers
;   CarDlm = delimiter [STR] 1 character 
;
; Examples:
;   (ALE_AlphaNumString2List "\"Abc\" 1.0 1 Xyz" " ")
;   => ("\"Abc\"" 1.0 1 "Xyz")
;   (ALE_AlphaNumString2List "\"Abc\" 1.0 1 Xyz ( 99" " ")
;   => nil
;   (ALE_AlphaNumString2List "\"Abc\" 1.0 1 Xyz ) 99" " ")
;   => nil
;   (ALE_AlphaNumString2List "\"Abc\" 1.0 1 Xyz \" 99" " ")
;   => nil
;   (ALE_AlphaNumString2List "\"Abc\" 1.0 1 Xyz , 99" " ")
;   => ("\"Abc\"" 1.0 1 "Xyz" "," 99)
;   (ALE_AlphaNumString2List "\"Abc\" 1.0 1 Xyz . 99" " ")
;   => nil
;   (ALE_AlphaNumString2List "\"Abc\" 1.0 1 Xyz .99" " ")
;   => ("\"Abc\"" 1.0 1 "Xyz" 0.99)
;
; Return Values:
;   [LIST] or nil on error
;
; Used functions: ALE_ReadString (ALE_AlphaNumString2List "132 LINE 15.23" " ")
;
(defun ALE_AlphaNumString2List (InpStr CarDlm / SttPos EndPos TmpLst TmpVal)
  (setq
    CarDlm (ascii CarDlm)
    SttPos 0
    EndPos (vl-string-position CarDlm InpStr)
  )
  (while EndPos
    (if
      (setq TmpVal
        (ALE_ReadString (substr InpStr (1+ SttPos) (- EndPos SttPos)))
      )
      (setq      
        TmpLst (cons TmpVal TmpLst)
        SttPos (1+ EndPos)
        EndPos (vl-string-position CarDlm InpStr SttPos)
      )
      (setq EndPos nil  TmpLst nil)
    )
  )
  (if (and TmpLst (setq TmpVal (ALE_ReadString (substr InpStr (1+ SttPos)))))
    (reverse (cons TmpVal TmpLst))
  )
)


; Marc'Antonio Alessi, Italy - http://alessi.xoom.it/alessi
;
; Function: ALE_ReadString
;
; Version 2.00 - 16/03/2007
;
; Description:
;   verify if the string can be converted in a real or integer
;   and return a real or integer
;   otherwise the original string
;
; Arguments:
;   StrVal = string [STR]
;
; Examples:
;   (ALE_ReadString "\"Abc\"") => "\"Abc\""
;   (ALE_ReadString "Xyz")     => "Xyz"
;   (ALE_ReadString ",")       => ","
;   (ALE_ReadString ".99")     => 0.99
;   (ALE_ReadString "1.0")     => 1.0
;   (ALE_ReadString "1")       => 1
;   (ALE_ReadString ".")       => "."
;   (ALE_ReadString "(")       => "("
;   (ALE_ReadString ")")       => ")"
;   (ALE_ReadString nil)       => error
;   (ALE_ReadString 0)         => error
;   (ALE_ReadString "\\\\server\\Test (test).dwg")
;               =>  "\\\\server\\Test (test).dwg"
;
; Return Values:
;   [STRING,REAL,INT]
;
(defun ALE_ReadString (StrVal)
  (cond
    ( (distof StrVal)
      (if (= 'REAL (type (read (strcat "0" StrVal))))
        (atof StrVal)
        (atoi StrVal)
      )
    )    
    ( StrVal )  
  )  
)
; Marc'Antonio Alessi, Italy - http://alessi.xoom.it/alessi
;
; Function: ALE_ReadString_Safe
;
; Version 1.11 - 27/04/2005
; Version 1.12 - 16/03/2007 - old name ALE_ReadString
;
; Description:
;   verify if the string can be converted in a real or integer
;   and return a real or integer
;   otherwise verify if the string is valid for read function
;   and return the original string
;
; Arguments:
;   StrVal = string [STR]
;
; Examples:
;   (ALE_ReadString_Safe "\"Abc\"") => "\"Abc\""
;   (ALE_ReadString_Safe "Xyz")     => "Xyz"
;   (ALE_ReadString_Safe ",")       => ","
;   (ALE_ReadString_Safe ".99")     => 0.99
;   (ALE_ReadString_Safe "1.0")     => 1.0
;   (ALE_ReadString_Safe "1")       => 1
;   (ALE_ReadString_Safe ".")       => nil
;   (ALE_ReadString_Safe "(")       => nil
;   (ALE_ReadString_Safe ")")       => nil
;   (ALE_ReadString_Safe nil)       => nil
;   (ALE_ReadString_Safe 0)         => nil
;   (ALE_ReadString_Safe "\\\\server\\Test (test).dwg")
;                    =>  "\\\\server\\Test (test).dwg"
;
; Return Values:
;   [STRING,REAL,INT] or nil on error
;
(defun ALE_ReadString_Safe (StrVal / TmpVal)
  (if
    (not
      (vl-catch-all-error-p 
        (setq TmpVal (vl-catch-all-apply 'distof (list StrVal)))
      )
    )
    (cond
      ( TmpVal
        (if (= 'REAL (type (read (strcat "0" StrVal))))
          (atof StrVal)
          (atoi StrVal)
        )
      )  
      ( (not 
          (vl-catch-all-error-p 
            (vl-catch-all-apply 'read (list StrVal))
          )
        )
        StrVal
      )
    )
  )
)

 

Marc'Antonio Alessi

http://alessi.xoom.it//alessi/Programmi.htm
(vl-string-translate "1234567890" "ie@mst.lan" "499825513610716")
2D Parametric for 2000-2013
Message 15 of 20


@AlessiMarc'Antonio wrote:

Maybe you need this result:

(ALE_AlphaNumString2List "132 LINE 15.23" " ")
(132 "LINE" 15.23)  >>> "LINE" as string 


If that's what you need, you can do it this way:

 

(defun S2L-RIS (str / maketype lst)
; = convert list-format String to List, converting type
; of text representing Reals/Integers, Space-delimited
  (defun maketype (x); make text representing reals/integers into those types
    (if (= (vl-string-trim ".0123456789" x) ""); has only numerical character(s)
      (if (wcmatch x "*.*"); then - does it contain decimal?
        (atof x); then - return real number
        (atoi x); else - return integer
      ); if
      x ; else - return original string
    ); if
  ); defun - maketype
  (while (wcmatch str "* *"); divide into pieces around spaces
    (setq lst ; list of sub-strings or reals/integers converted from them
      (append
        lst
        (list (maketype (substr str 1 (vl-string-position 32 str))))
          ; text prior to first space
      ); end append
    ); end setq
    (setq str (substr str (+ (vl-string-position 32 str) 2)))
      ; text from after first space to end
  ); end while
  (setq lst (append lst (list (maketype str)))); do remaining text after last space
); defun

 

Then:

 

Command: (S2L-RIS "132 LINE 15.23")
(132 "LINE" 15.23)

 

EDIT:  If your string might contain things like feet/inches and/or fractions, the above wouldn't be enough.

Kent Cooper, AIA
Message 16 of 20
phanaem
in reply to: Kent1Cooper

My variant

 

((lambda (str)
   (mapcar
     (function
       (lambda (x)
         (if
           (eq (type x) 'SYM)
            (vl-symbol-name x)
            x
         )
       )
     )
     (read
       (strcat "(" str ")")
     )
   )
 )
  "132 LINE 15.23"
)

 

Message 17 of 20
Kent1Cooper
in reply to: phanaem


@phanaem wrote:

My variant

....

(vl-symbol-name x)

....


Interestingly concise....  However, the AutoLISP Reference reveals that (vl-symbol-name) converts all characters to UPPER CASE.  Applying the routine to

"abc LINE 15 23.456"

returns

("ABC" "LINE" 15 23.456)

 

Whether that matters would be up to the OP [maybe they don't use lower-case characters in whatever circumstances this would apply to].

Kent Cooper, AIA
Message 18 of 20

Comando: (ALE_AlphaNumString2List "\"Abc\" 1.0 1 Xyz" " ")
("\"Abc\"" 1.0 1 "Xyz")
Comando: (ALE_AlphaNumString2List "\"Abc\" 1.0 1 Xyz ( 99" " ")
nil
Comando: (ALE_AlphaNumString2List "\"Abc\" 1.0 1 Xyz ) 99" " ")
nil
Comando: (ALE_AlphaNumString2List "\"Abc\" 1.0 1 Xyz \" 99" " ")
nil
Comando: (ALE_AlphaNumString2List "\"Abc\" 1.0 1 Xyz , 99" " ")
("\"Abc\"" 1.0 1 "Xyz" "," 99)
Comando: (ALE_AlphaNumString2List "\"Abc\" 1.0 1 Xyz . 99" " ")
nil
Comando: (ALE_AlphaNumString2List "\"Abc\" 1.0 1 Xyz .99" " ")
("\"Abc\"" 1.0 1 "Xyz" 0.99)
Comando: (ALE_AlphaNumString2List "132 LINE 15.23"  " ")
(132 "LINE" 15.23)

Comando: (S2L-RIS "\"Abc\" 1.0 1 Xyz")
("\"Abc\"" 1.0 1 "Xyz")
Comando: (S2L-RIS "\"Abc\" 1.0 1 Xyz ( 99")
("\"Abc\"" 1.0 1 "Xyz" "(" 99)
Comando: (S2L-RIS "\"Abc\" 1.0 1 Xyz ) 99")
("\"Abc\"" 1.0 1 "Xyz" ")" 99)
Comando: (S2L-RIS "\"Abc\" 1.0 1 Xyz \" 99")
("\"Abc\"" 1.0 1 "Xyz" "\"" 99)
Comando: (S2L-RIS "\"Abc\" 1.0 1 Xyz , 99")
("\"Abc\"" 1.0 1 "Xyz" "," 99)
Comando: (S2L-RIS "\"Abc\" 1.0 1 Xyz . 99")
("\"Abc\"" 1.0 1 "Xyz" 0.0 99)
Comando: (S2L-RIS "\"Abc\" 1.0 1 Xyz .99")
("\"Abc\"" 1.0 1 "Xyz" 0.99)
Comando: (S2L-RIS "132 LINE 15.23")
(132 "LINE" 15.23)

 

What do you think about?

What kind of results do you prefear?

 

Marc'Antonio Alessi

http://alessi.xoom.it//alessi/Programmi.htm
(vl-string-translate "1234567890" "ie@mst.lan" "499825513610716")
2D Parametric for 2000-2013
Message 19 of 20


@AlessiMarc'Antonio wrote:

....

Comando: (ALE_AlphaNumString2List "\"Abc\" 1.0 1 Xyz . 99" " ")
nil
....

Comando: (S2L-RIS "\"Abc\" 1.0 1 Xyz . 99")
("\"Abc\"" 1.0 1 "Xyz" 0.0 99)
....

What do you think about?

What kind of results do you prefear?


Those are some peculiar initial text strings you've tested the routines with.  I haven't studied the operation of (ALE_AlphaNumString2List) closely enough to understand why it returns nil for half of them.  The only thing that (S2L-RIS) returns differently than I would probably want is the conversion of the isolated period/decimal point [which it wouldn't have occurred to me to try] to 0.0.  That could be prevented easily enough, if it's at all likely to be part of the OP's initial text string.

Kent Cooper, AIA
Message 20 of 20


@Kent1Cooper wrote:

 That could be prevented easily enough, if it's at all likely to be part of the OP's initial text string.

Yes, you are correct, my functions are used to avoid the incorrect list output with strings containing generic bad data.

 

Ciao.

Marc'Antonio Alessi

http://alessi.xoom.it//alessi/Programmi.htm
(vl-string-translate "1234567890" "ie@mst.lan" "499825513610716")
2D Parametric for 2000-2013

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost