Author Topic: need some suggestions on converting string to list  (Read 4822 times)

0 Members and 1 Guest are viewing this topic.

andrew_nao

  • Guest
need some suggestions on converting string to list
« on: April 05, 2012, 09:40:06 AM »
sorry for the title, i wasnt sure on what to name it.

im converting a string to a list using Alanjt's code listed here (thank you)
http://www.theswamp.org/index.php?topic=32845.0

im using a space as the separator, however if the item is a dimension like 6 1/2" and using the separator splits that into 2 list items, what can i do to not separate dimensions like that but still use the space as a separator to split my string into a list.. or is this just not possible?


Lee Mac

  • Seagull
  • Posts: 12922
  • London, England
Re: need some suggestions on converting string to list
« Reply #1 on: April 05, 2012, 10:02:31 AM »
I'm guessing this is related to this task:

http://www.theswamp.org/index.php?topic=41407.0

andrew_nao

  • Guest
Re: need some suggestions on converting string to list
« Reply #2 on: April 05, 2012, 10:17:38 AM »
yes Lee, it is but new topic

Lee Mac

  • Seagull
  • Posts: 12922
  • London, England
Re: need some suggestions on converting string to list
« Reply #3 on: April 05, 2012, 10:22:05 AM »
Did Irneb not solve your problem?

andrew_nao

  • Guest
Re: need some suggestions on converting string to list
« Reply #4 on: April 05, 2012, 10:25:48 AM »
Did Irneb not solve your problem?

no ones really did. i have too many different scenarios for any of that to work. even the old code i was using didnt work properly.
so im starting over by breaking down a string to list then taking the number, converting it, then adding it back into the list and then convert the list back to a string.
thats the plan anyway

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: need some suggestions on converting string to list
« Reply #5 on: April 05, 2012, 10:36:01 AM »
Could you state a sample string? You'd probably need to find some way of distinguishing where the measurement starts and/or stops.

Another way could be to use the code I added here: http://www.theswamp.org/index.php?topic=41407.msg465217#msg465217

In particular the ExtractImperial function. That would extract only the dimension portion from the string. Thereafter you could split the string at the point where you find that and perform the normal str2lst idea on the 2 sides. Then simply an append.

The basis for this idea is contained in that thread as well. I mean the AddMetric method uses the string returned from ExtractImperial to search for the position in the original string - it simply uses vl-string-subst. You could use vl-string-search in the same way.
« Last Edit: April 05, 2012, 10:39:30 AM by irneb »
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: need some suggestions on converting string to list
« Reply #6 on: April 05, 2012, 10:57:29 AM »
I cannot figure why it "won't" work for you. Here's what I mean:
Code - Auto/Visual Lisp: [Select]
  1.  
  2. (defun ExtractImperial  (str / len n m c res)
  3.   (setq n 0 len (strlen str) res "")
  4.   (while (and (not (wcmatch res "*#',*#\"")) (< n len))
  5.     (while (and (<= (setq n (1+ n)) len) (not (wcmatch (substr str n 1) "[0-9]"))))
  6.     (setq m 0)
  7.     (while (and (<= (+ n (setq m (1+ m))) (1+ len)) (not (wcmatch (substr str n m) "*[~-'0-9/\" ]*"))))
  8.     (setq res (vl-string-trim " /-" (substr str n (1- m))) n (+ n m)))
  9.   (if (wcmatch res "*#',*#\"") res ""))
  10.  
  11. (defun str2lst (str / left dim pos split)
  12.   (defun split (str / )
  13.     (setq str (vl-string-translate " " "\002" (vl-string-trim " " str)))
  14.     (while (wcmatch str "*\002*") (setq str (vl-string-subst "\" \"" "\002" str)))
  15.     (read (strcat "(\"" str "\")")))
  16.   (vl-remove-if '(lambda (a) (eq a ""))
  17.     (if (not (eq (setq dim (ExtractImperial str)) ""))
  18.       (append (split (substr str 1 (setq pos (vl-string-search dim str)))) (list dim)
  19.               (str2lst (substr str (+ 1 pos (strlen dim)))))
  20.       (split str))))
Some test cases:
Code: [Select]
_$ (str2lst "Test Test Test 6'-5 2/3\"")
("Test" "Test" "Test" "6'-5 2/3\"")
_$ (str2lst "6'-5 2/3\"")
("6'-5 2/3\"")
_$ (str2lst "6'-5 2/3\" test test")
("6'-5 2/3\"" "test" "test")
_$ (str2lst "6'-5 2/3\"test test")
("6'-5 2/3\"" "test" "test")
_$ (str2lst "test6'-5 2/3\"test test")
("test" "6'-5 2/3\"" "test" "test")
_$ (str2lst "test 6'-5 2/3\" test test6'-5 2/3\"test test")
("test" "6'-5 2/3\"" "test" "test" "6'-5 2/3\"" "test" "test")
_$ (str2lst "Test Test Test 6'-5 2/3\" test")
("Test" "Test" "Test" "6'-5 2/3\"" "test")
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

andrew_nao

  • Guest
Re: need some suggestions on converting string to list
« Reply #7 on: April 05, 2012, 11:11:04 AM »
Could you state a sample string? You'd probably need to find some way of distinguishing where the measurement starts and/or stops.


yes i can. something like
four (4) @ 14 1/2" 90%%d apart

your coding works otherwise its when you throw the least expected string in there it doesnt convert.

i guess thats where i would need to find where the measure starts n stops

andrew_nao

  • Guest
Re: need some suggestions on converting string to list
« Reply #8 on: April 05, 2012, 11:14:37 AM »
i need to just separate the dimension and any number after it with a dash or a comma.   then it works.

i guess theses old dogs will just have to learn a new trick and change the way they do things

andrew_nao

  • Guest
Re: need some suggestions on converting string to list
« Reply #9 on: April 05, 2012, 11:18:58 AM »
spoke to soon

2 5/8" O.D. x 1 5/16" I.D.
it results in

2 5/8" (67mm) O.D. x 1 5/16" I.D.

leaves out the 1 5/16"

there is always something...  :-( :-o

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: need some suggestions on converting string to list
« Reply #10 on: April 06, 2012, 02:59:46 AM »
Ok, I thought that regular expressions should be used here. Seems it's not just more efficient, but also a lot more comprehensive.

I'm using the RX:Search function from my code here: http://caddons.svn.sourceforge.net/viewvc/caddons/Libraries/RegExp.LSP?revision=62&view=markup

Some tests:
Code: [Select]
_$ (RX:Search "four (4) @ 14 1/2\" 90%%d apart" "((\\d+'[ -]\\d \\d+/\\d+\")|(\\d+'[ -]\\d\")|(\\d+')|(\\d+ \\d+/\\d+\")|(\\d+/\\d+\"))")
((11 . "14 1/2\""))
_$ (RX:Search "2 5/8\" O.D. x 1 5/16\" I.D." "((\\d+'[ -]\\d \\d+/\\d+\")|(\\d+'[ -]\\d\")|(\\d+')|(\\d+ \\d+/\\d+\")|(\\d+/\\d+\"))")
((0 . "2 5/8\"") (14 . "1 5/16\""))
The 1st number is the start index where the pattern was found, the string is the portion matching the pattern. That would make it simpler to use substr to split the string into it's portions.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: need some suggestions on converting string to list
« Reply #11 on: April 06, 2012, 03:02:58 AM »
Sorry the regular expression search pattern should be changed to allow for the case where there's only an inch number shown (no feet and no fractions):
Quote
"((\\d+'[ -]\\d \\d+/\\d+\")|(\\d+'[ -]\\d\")|(\\d+')|(\\d+ \\d+/\\d+\")|(\\d+/\\d+\")|(\\d+\"))"
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: need some suggestions on converting string to list
« Reply #12 on: April 06, 2012, 03:25:42 AM »
Here's the AddMetric function - using the RX:Search:
Code: [Select]
(defun AddMetric (str /)
  (foreach val (reverse (RX:Search str "((\\d+'[ -]\\d \\d+/\\d+\")|(\\d+'[ -]\\d\")|(\\d+')|(\\d+ \\d+/\\d+\")|(\\d+/\\d+\")|(\\d+\"))"))
    (setq str (vl-string-subst (strcat (cdr val) " (" (rtos (cvunit (distof (cdr val) 4) "inch" "mm") 2 0) "mm)") (cdr val) str (car val))))
  str)

Seems to work fine now:
Code: [Select]
_$ (AddMetric "four (4) @ 14 1/2\" 90%%d apart")
"four (4) @ 14 1/2\" (368mm) 90%%d apart"
_$ (AddMetric "2 5/8\" O.D. x 1 5/16\" I.D.")
"2 5/8\" (67mm) O.D. x 1 5/16\" (33mm) I.D."
_$ (AddMetric "5'-2 5/8\" O.D. x 1 5/16\" I.D.")
"5'-2 5/8\" (1591mm) O.D. x 1 5/16\" (33mm) I.D."
_$ (AddMetric "5' 2 5/8\" O.D. x 1 5/16\" I.D.")
"5' 2 5/8\" (1591mm) O.D. x 1 5/16\" (33mm) I.D."
_$ (AddMetric "12'-6\"")
"12'-6\" (3810mm)"
_$ (AddMetric "12'-6\" dia circle")
"12'-6\" (3810mm) dia circle"
_$ (AddMetric "this is a 12'-6 1/2\" dia circle")
"this is a 12'-6 1/2\" (3823mm) dia circle"
_$ (AddMetric "this is a 12' dia circle")
"this is a 12' (3658mm) dia circle"
« Last Edit: April 06, 2012, 03:32:41 AM by irneb »
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

andrew_nao

  • Guest
Re: need some suggestions on converting string to list
« Reply #13 on: April 09, 2012, 08:44:43 AM »
it seems that if i use your search function from the link you gave, i need the rest of the functions also for it to work? it keeps asking for the other functions of your code to use the search function... or am i missing something in the translation?


andrew_nao

  • Guest
Re: need some suggestions on converting string to list
« Reply #14 on: April 09, 2012, 09:17:06 AM »
ok so i think i figured this out, however it doesnt work for me like it did you

Command: (addmetric "2 5/8\" O.D. x 1 5/16\" I.D.")
"2 5/8\" (67mm) O.D. x 1 5/16\" I.D."


here is the code i have
Code: [Select]
;; conversion code by irneb from theswamp.org

(defun RX:Search (string pattern / lst col item)

   ;(if (RX:Start)
     ;(progn
       (vlax-Put *RX-Link* 'Pattern pattern) ;Set the pattern to match
       ;; Get the collection of match objects
       (setq col (vl-catch-all-apply 'vlax-Invoke (list *RX-Link* 'Execute string)))
       (if (not (vl-catch-all-error-p col))
         (progn
          ;; Loop through collection & place into return list
           (vlax-for item col
             ;; Get the position & length
             (setq lst (cons (cons (vlax-Get item 'FirstIndex) (vlax-Get item 'Value)) lst))
             (vlax-release-object item) ;Release the match object
           ) ;_ end of while
          (vlax-release-object col) ;Release the collection object
         ) ;_ end of progn
      ) ;_ end of if
       (reverse lst) ;Return list in correct order
     ;) ;_ end of progn
   ;) ;_ end of if
) ;_ end of defun
 


(defun ExtractImperial (str / len n m c res)
  (setq n 0 len (strlen str) res "")
  (while (and (not (wcmatch res "*#',*#\"")) (< n len))
    (while (and (<= (setq n (1+ n)) len) (not (wcmatch (substr str n 1) "[0-9]"))))
    (setq m 0)
    (while (and (<= (+ n (setq m (1+ m))) (1+ len)) (not (wcmatch (substr str n m) "*[~-'0-9/\" ]*"))))
    (setq res (vl-string-trim " /-" (substr str n (1- m))) n (+ n m)))
  (if (wcmatch res "*#',*#\"") res "")
)

(defun AddMetric (str /)
  (foreach val (reverse
  (RX:Search str "((\\d+'[ -]\\d \\d+/\\d+\")|(\\d+'[ -]\\d\")|(\\d+')|(\\d+ \\d+/\\d+\")|(\\d+/\\d+\")|(\\d+\"))"))
    (setq str (vl-string-subst (strcat (cdr val) " (" (rtos (cvunit (distof (cdr val) 4) "inch" "mm") 2 0) "mm)") (cdr val) str (car val)))) str)

; code from me
(DEFUN C:test ()

;
;; GET ENTITY
;
       (SETQ MT (ENTSEL "\nPLEASE PICK DESIRED TEXT"))
       (SETQ MTED (ENTGET (CAR MT)))
       (SETQ MTLL (ASSOC '1 MTED))
       (SETQ MTT (CDR MTLL))
   (setq MTT (addmetric MTT))
(SETQ TLN (CONS 1 MTT))
(SETQ TLNN (SUBST TLN MTLL MTED))
(ENTMOD TLNN)
(PRINC)
)
« Last Edit: April 09, 2012, 09:32:49 AM by andrew_nao »

andrew_nao

  • Guest
Re: need some suggestions on converting string to list
« Reply #15 on: April 09, 2012, 09:38:59 AM »
now its not working

tried on a new dwg
PLEASE PICK DESIRED TEXT; error: bad argument type: VLA-OBJECT nil

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: need some suggestions on converting string to list
« Reply #16 on: April 09, 2012, 10:31:12 AM »
it seems that if i use your search function from the link you gave, i need the rest of the functions also for it to work? it keeps asking for the other functions of your code to use the search function... or am i missing something in the translation?
Yes you are correct, you need an absolute minimum of the RX:Search, RX:Start & RX:Set functions to be loaded in order to use my regular expression library. Fore ease, here's the 3 defuns:
Code - Auto/Visual Lisp: [Select]
  1.  
  2. ;;; -------------------------------------------------------------------------------------
  3. ;;; Get a reference to the Regular Expression Object object
  4. ;;; -------------------------------------------------------------------------------------
  5. ;;; Result: a vla object for the regular expression tools
  6. ;;; -------------------------------------------------------------------------------------
  7. (defun RX:Start (/)
  8.   (if (or (not *RX-Link*)
  9.           (not (setq *RX-Link* (vl-bb-ref '*RX-Link*)))
  10.           (vlax-object-released-p *RX-Link*)
  11.       ) ;_ end of or
  12.     (progn
  13.       (vl-bb-set '*RX-Link* (setq *RX-Link* (vlax-get-or-create-object "VBScript.RegExp")))
  14.       (RX:Set t t t)
  15.     ) ;_ end of progn
  16.   ) ;_ end of if
  17.   *RX-Link*
  18. ) ;_ end of defun
  19.  
  20. ;;; -------------------------------------------------------------------------------------
  21. ;;; Change settings for regexp
  22. ;;; -------------------------------------------------------------------------------------
  23. ;;; Arguments:
  24. ;;; multiline  = nil -> Stop- / t -> Don't stop at line ends
  25. ;;; global     = nil -> only find 1st occurence; t -> find all occurences
  26. ;;; ignorecase = nil -> case sensitive; t -> case insensitive
  27. ;;; -------------------------------------------------------------------------------------
  28. ;;; Result: undefined
  29. ;;; -------------------------------------------------------------------------------------
  30. (defun RX:Set (multiline global ignorecase)
  31.   (if *RX-Link*
  32.     (progn
  33.       (vlax-put *RX-Link*
  34.                 'Multiline
  35.                 (if multiline
  36.                   -1
  37.                   0
  38.                 ) ;_ end of if
  39.       ) ;_ end of vlax-put
  40.       (vlax-put *RX-Link*
  41.                 'Global
  42.                 (if global
  43.                   -1
  44.                   0
  45.                 ) ;_ end of if
  46.       ) ;_ end of vlax-put
  47.       (vlax-put *RX-Link*
  48.                 'IgnoreCase
  49.                 (if ignorecase
  50.                   -1
  51.                   0
  52.                 ) ;_ end of if
  53.       ) ;_ end of vlax-put
  54.     ) ;_ end of progn
  55.   ) ;_ end of if
  56. ) ;_ end of defun
  57.  
  58. ;;; -------------------------------------------------------------------------------------
  59. ;;; Find positions matching the pattern in the string
  60. ;;; -------------------------------------------------------------------------------------
  61. ;;; Arguments:
  62. ;;; string      = The string to search through
  63. ;;; pattern     = The regular expression patter to search for
  64. ;;; -------------------------------------------------------------------------------------
  65. ;;; Result: A list containing dotted pairs of (Position . Value)
  66. ;;; -------------------------------------------------------------------------------------
  67. ;;; Example
  68. ;;; (RX:Search "\"Test,6\",34,45.6,\"48\"" "(\\s*\"[^\"]*\"\s*,)|(\\s*[^,]*\\s*,)")
  69. ;;; Will return a list containing the positions & values after parsing the CVS string.
  70. ;;; ((0 . "\"Test,6\",") (9 . "34,") (12 . "45.6,"))
  71. ;;; -------------------------------------------------------------------------------------
  72. (defun RX:Search (string pattern / lst col item)
  73.   (if (RX:Start)
  74.     (progn
  75.       (vlax-Put *RX-Link* 'Pattern pattern) ;Set the pattern to match
  76.       ;; Get the collection of match objects
  77.       (setq col (vl-catch-all-apply 'vlax-Invoke (list *RX-Link* 'Execute string)))
  78.       (if (not (vl-catch-all-error-p col))
  79.         (progn
  80.           ;; Loop through collection & place into return list
  81.           (vlax-for item col
  82.             ;; Get the position & length
  83.             (setq lst (cons (cons (vlax-Get item 'FirstIndex) (vlax-Get item 'Value)) lst))
  84.             (vlax-release-object item) ;Release the match object
  85.           ) ;_ end of while
  86.           (vlax-release-object col) ;Release the collection object
  87.         ) ;_ end of progn
  88.       ) ;_ end of if
  89.       (reverse lst) ;Return list in correct order
  90.     ) ;_ end of progn
  91.   ) ;_ end of if
  92. ) ;_ end of defun

As for the VLA-OBJECT nil error, ensure that vl-load-com is called at least once somewhere in your code. The Regular Expression functions uses the VBScripting RegExp ActiveX library - and you can only use that if the visual lisp com interface is loaded.

It seems to work fine for me with this code:
Code - Auto/Visual Lisp: [Select]
  1. (defun AddMetric (str /)
  2.   (foreach val (reverse (RX:Search str "((\\d+'[ -]\\d \\d+/\\d+\")|(\\d+'[ -]\\d\")|(\\d+')|(\\d+ \\d+/\\d+\")|(\\d+/\\d+\")|(\\d+\"))"))
  3.     (setq str (vl-string-subst (strcat (cdr val) " (" (rtos (cvunit (distof (cdr val) 4) "inch" "mm") 2 0) "mm)") (cdr val) str (car val))))
  4.   str)
  5.  
  6. (defun c:AddMetric (/ ss str)
  7.   (if (and (ssget '((0 . "TEXT,MTEXT")))
  8.     (progn
  9.       (vlax-for eo ss
  10.         (setq str (AddMetric (vla-get-TextString eo)))
  11.         (if (not (eq str (vla-get-TextString eo)))
  12.           (vla-put-TextString eo str)))
  13.       (vla-Delete ss)))
  14.   (progn))
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

andrew_nao

  • Guest
Re: need some suggestions on converting string to list
« Reply #17 on: April 09, 2012, 02:47:37 PM »
got it working, i was missing the vl-load-com

super thanks irneb, much appreciated

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: need some suggestions on converting string to list
« Reply #18 on: April 09, 2012, 11:33:35 PM »
Glad you got it working finally.  ;D
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

andrew_nao

  • Guest
Re: need some suggestions on converting string to list
« Reply #19 on: April 10, 2012, 12:13:43 PM »
ive spoken to soon again


example:
EL. 123'-10"
results in
EL. 123' (37490mm)-10" (254mm)

would this have something to do with the rs:search function inside the addmetric function?


fixed... had to add this in the search
(\\d+'[- ]\\d\\d+ \\d+/\\d+\")|(\\d+'[- ]\\d\\d+\")
« Last Edit: April 10, 2012, 02:37:52 PM by andrew_nao »

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: need some suggestions on converting string to list
« Reply #20 on: April 11, 2012, 01:04:48 AM »
Awesome! Glad you could figure out those RegExp codes!

Though my RegExp.LSP contains a comment at the end describing the special characters, I find it useful to search through these 2 sites for some tricks:
http://www.regular-expressions.info/examples.html
http://regexlib.com/?AspxAutoDetectCookieSupport=1
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.