Author Topic: Split String To Strings and Numbers  (Read 12663 times)

0 Members and 1 Guest are viewing this topic.

Grrr1337

  • Swamp Rat
  • Posts: 812
Split String To Strings and Numbers
« on: October 01, 2017, 05:12:00 PM »
Hi again guys,
I was trying to figure out a function that does this:
Code - Auto/Visual Lisp: [Select]
  1.  _$ (foo "Hi123SplitThis12.345String25-20") -> ("Hi" 123 "SplitThis" 12.345 "String" 25 "-" 20)
Basically breaking a string into a list of strings and numbers.

I've searched quite a while, but the closest result was from Lee's LM:SplitString function:
Code - Auto/Visual Lisp: [Select]
  1. _$ (LM:splitstring "Hi123SplitThis12.345String25-20")
  2. ("H" "i" 123 "S" "p" "l" "i" "t" "T" "h" "i" "s" 12.345 "S" "t" "r" "i" "n" "g" 25 "-" 20)
As you can see it does character breaking, and groups those that form potential numbers.
That looks good, but if one has alphabetical fragments of unknown length the 'nth' position of the number or the string fragment would be lost:
Code - Auto/Visual Lisp: [Select]
  1. _$ (LM:splitstring "AB-420-HE5")
  2. ("A" "B" "-" 420 "-" "H" "E" 5)
  3.  
  4. _$ (LM:splitstring "ASB-430-HS56")
  5. ("A" "S" "B" "-" 430 "-" "H" "S" 56)

Atleast the labeling str patterns look more like this (where the strlen varies).
And yea I know that I could filter out the numbers in a new list and process them, but thats not the point.



So when using his subfunction along with this one (wow, he wrote the 2nd function aswell) :
Code - Auto/Visual Lisp: [Select]
  1. ; https://www.theswamp.org/index.php?topic=53354.msg580794#msg580794
  2. (defun GroupListByFoo ( prd lst / rtn tmp ) ; Lee Mac
  3.   (foreach itm lst
  4.     (if (apply prd (list itm))
  5.       (setq rtn (vl-list* (list itm) (reverse tmp) rtn) tmp nil)
  6.       (setq tmp (cons itm tmp))
  7.     )
  8.    
  9.   )
  10.   (vl-remove nil (reverse (cons (reverse tmp) rtn)))
  11. ); defun GroupListByFoo

I've managed to write a solution:
Code - Auto/Visual Lisp: [Select]
  1. _$ (mapcar
  2.   '(lambda (x) (cond ( (= 1 (length x)) (car x) ) ( (apply 'strcat x) ) ))
  3.   (GroupListByFoo
  4.     '(lambda (x) (numberp x))
  5.     (LM:splitstring "Hi123SplitThis12.345String25-20")
  6.   )
  7. )
  8. ("Hi" 123 "SplitThis" 12.345 "String" 25 "-" 20)
But honestly I think that the above approach sucks, due the amount of proccessing/manupulating a single string..
So any ideas to write a better one from scratch?
Does this sound like a {Challenge} ? :lol:
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

Tharwat

  • Swamp Rat
  • Posts: 710
  • Hypersensitive
Re: Split String To Strings and Numbers
« Reply #1 on: October 02, 2017, 02:10:28 AM »
Hi,

Maybe this?

Code - Auto/Visual Lisp: [Select]
  1. (defun ConcatStrWithinList (lst / str rtn)
  2. ;; Tharwat - 02.Oct.2017  ;;
  3.   (setq str "")
  4.   (while lst
  5.     (if (numberp (car lst)) (setq rtn (cons (car lst) rtn) lst (cdr lst))
  6.       (progn (while (and lst (= (type (car lst)) 'str))
  7.                (setq str (strcat str (car lst))
  8.                      lst (cdr lst)
  9.                      )
  10.                )
  11.         (setq rtn (cons str rtn) str "")
  12.         )
  13.       )
  14.     )
  15.   (reverse rtn)
  16.   )
  17.  

eg:
Code - Auto/Visual Lisp: [Select]
  1. _$ (ConcatStrWithinList '("H" "i" 123 "S" "p" "l" "i" "t" "T" "h" "i" "s" 12.345 "S" "t" "r" "i" "n" "g" 25 "-" 20))
  2. ("Hi" 123 "SplitThis" 12.345 "String" 25 "-" 20)
  3.  

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: Split String To Strings and Numbers
« Reply #2 on: October 02, 2017, 06:39:55 AM »
Hi Tharwat,

That seems better, thanks! :)

Code - Auto/Visual Lisp: [Select]
  1. _$ (ConcatStrWithinList (LM:splitstring "Hi123SplitThis12.345String25-20"))
  2. ("Hi" 123 "SplitThis" 12.345 "String" 25 "-" 20)

But actually I was trying to combine all of this into a single function, i.e.:
Code - Auto/Visual Lisp: [Select]
  1. (foo "Hi123SplitThis12.345String25-20") -> ("Hi" 123 "SplitThis" 12.345 "String" 25 "-" 20)




So I guess thats a success... :

Code - Auto/Visual Lisp: [Select]
  1. ; Source code by Lee Mac - heavily modified his (LM:splitstring) function
  2. (defun String->ListOfStringsAndNumbers ( str / L r )
  3.   (and ; https://www.theswamp.org/index.php?topic=53496.0
  4.     (eq 'STR (type str))
  5.     (setq L (mapcar 'chr (vl-string->list str)))
  6.     (setq L
  7.       (apply 'append
  8.         (mapcar
  9.           (function
  10.             (lambda ( a b c / ai bi ci an bn cn)
  11.               (mapcar 'set '(ai bi ci) (mapcar '(lambda (x) (if x (ascii x))) (list a b c)))
  12.               (mapcar 'set '(an bn cn) (mapcar '(lambda (x) (cond ( (and x (/= "." x)) (numberp (read x))) ( (= "." x) ))) (list a b c)))
  13.               (cond
  14.                 ( (= "\\" b) (list " " "\"" "\\" b "\"" " ") )
  15.                 (
  16.                   ; (append ; this block is just informative and shall be erased
  17.                   ; (if a
  18.                   ; (if (or (and an (not bn)) (and (not an) bn)) (list " " "\""))
  19.                   ; (list "\"")
  20.                   ; )
  21.                   ; (list b)
  22.                   ; (if c
  23.                   ; (if (or (and cn (not bn)) (and (not cn) bn)) (list "\"" " " ))
  24.                   ; (list "\"")
  25.                   ; )
  26.                   ; ); append
  27.                   (list
  28.                     (if a
  29.                       (if (or (and an (not bn)) (and (not an) bn)) (strcat " " "\"") "")
  30.                       "\""
  31.                     )
  32.                     b
  33.                     (if c
  34.                       (if (or (and cn (not bn)) (and (not cn) bn)) (strcat "\"" " " ) "")
  35.                       "\""
  36.                     )
  37.                   ); list
  38.                 )
  39.               )
  40.             )
  41.           )
  42.           (cons nil L) L (append (cdr L) '(( )))
  43.         )
  44.       )
  45.     )
  46.     (setq r
  47.       (mapcar
  48.         (function
  49.           (lambda (x / n)
  50.             (cond
  51.               ( (= "." x) )
  52.               ( (wcmatch x "`.*")
  53.                 (setq n (read (strcat "0" x)))
  54.               )
  55.               ( (setq n (read x)) )
  56.             )
  57.             (cond
  58.               ( (numberp n) n)
  59.               (x)
  60.             ); cond
  61.           ); lambda
  62.         ); function
  63.         (read
  64.           (strcat "("
  65.             (apply 'strcat L)
  66.             ")"
  67.           )
  68.         )
  69.       )
  70.     )
  71.   ); and
  72.   r
  73. ); defun String->ListOfStringsAndNumbers

Results:
Code - Auto/Visual Lisp: [Select]
  1. _$ (String->ListOfStringsAndNumbers "Hi123SplitThis12.345String25-20")
  2. ("Hi" 123 "SplitThis" 12.345 "String" 25 "-" 20)
  3.  
  4. _$ (String->ListOfStringsAndNumbers "Hi.123SplitThis12.345String25-20")
  5. ("Hi" 0.123 "SplitThis" 12.345 "String" 25 "-" 20)
  6.  
  7. _$ (String->ListOfStringsAndNumbers "Hi..123SplitThis12.345String25-20")
  8. ("Hi" "..123" "SplitThis" 12.345 "String" 25 "-" 20)




BTW heres Lee's code I mentioned previously (couldn't find it officially on his website) :
Code - Auto/Visual Lisp: [Select]
  1. ;; Split String  -  Lee Mac
  2. ;; Splits a string into a list of text and numbers
  3.  
  4. (defun LM:splitstring ( str )
  5.   (
  6.     (lambda ( l )
  7.       (read
  8.         (strcat "("
  9.           (vl-list->string
  10.             (apply 'append
  11.               (mapcar
  12.                 (function
  13.                   (lambda ( a b c )
  14.                     (cond
  15.                       (   (= 92 b)
  16.                       (list 32 34 92 b 34 32)
  17.                     )
  18.                     (   (or (< 47 b 58)
  19.                       ;(and (= 45 b) (< 47 c 58) (not (< 47 a 58)))
  20.                       (and (= 46 b) (< 47 a 58) (< 47 c 58))
  21.                     )
  22.                     (list b)
  23.                     )
  24.                     (   (list 32 34 b 34 32))
  25.                   )
  26.                   )
  27.                 )
  28.                 (cons nil l) l (append (cdr l) '(( )))
  29.               )
  30.             )
  31.           )
  32.           ")"
  33.         )
  34.       )
  35.     )
  36.     (vl-string->list str)
  37.   )
  38. )

No idea how he is used to manipulate ASCII like that, but I agree that would be faster, than my chr conversion.  :thinking:

Thanks again for your input!
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

VovKa

  • Water Moccasin
  • Posts: 1628
  • Ukraine
Re: Split String To Strings and Numbers
« Reply #3 on: October 02, 2017, 09:14:12 AM »
quotes, double quotes, parenthesis will not pass through read function

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: Split String To Strings and Numbers
« Reply #4 on: October 02, 2017, 10:11:11 AM »
quotes, double quotes, parenthesis will not pass through read function

Thanks Vovka, I was aware only about the dot "." issue!  :rolleyes2:

How about this quick-dirty fix? :

Code - Auto/Visual Lisp: [Select]
  1. ; _$ (read "'") -> Error: EOF after quote on input
  2. ; _$ (read "(") -> Error: malformed list on input
  3. ; _$ (read ")") -> Error: extra right paren on input
  4. ; _$ (read """") -> Error: too many arguments
  5. ; _$ (read ".") -> Error: misplaced dot on input
  6. ; _$ (read "....") -> Error: misplaced dot on input
  7. (setq ReadCarefully
  8.   (lambda (x / r)
  9.     (cond
  10.       ( (vl-catch-all-error-p (setq r (vl-catch-all-apply 'read (list x)))) x)
  11.       (r)
  12.     )
  13.   )
  14. )
  15.  
  16. _$ (mapcar 'ReadCarefully '("'" "(" ")" """" "." "..."))
  17. ("'" "(" ")" nil nil "." "...")
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

fools

  • Newt
  • Posts: 72
  • China
Re: Split String To Strings and Numbers
« Reply #5 on: October 02, 2017, 11:27:07 AM »
Code - Auto/Visual Lisp: [Select]
  1. ;; Split String  -  Lee Mac
  2. ;; Splits a string into a list of text and numbers
  3. ;; Modified by Fools , 2011.10.2
  4. ;; (LM:splitstring-F1 "Hi123SplitThis12.345String25-20")
  5. ;; ("Hi" 123 "SplitThis" 12.345 "String" 25 "-" 20)
  6. (defun LM:splitstring-F1 (str)
  7.   ((lambda (l)
  8.      (read
  9.        (strcat "("
  10.                (vl-list->string
  11.                  (apply 'append
  12.                         (mapcar (function (lambda (a b c)
  13.                                             (cond ((= 92 b) (list 32 34 92 b 34 32))
  14.                                                   ((or (< 47 b 58) (and (= 46 b) (< 47 a 58) (< 47 c 58))) (list b))
  15.                                                   ((cond ((not a) (list 34 b))
  16.                                                          ((and (< 47 a 58) (< 47 c 58)) (list 32 34 b 34 32))
  17.                                                          ((< 47 a 58) (list 32 34 b))
  18.                                                          ((< 47 c 58) (list b 34 32))
  19.                                                          ((not c) (list b 34))
  20.                                                          ((list b))
  21.                                                    )
  22.                                                   )
  23.                                             )
  24.                                           )
  25.                                 )
  26.                                 (cons nil l)
  27.                                 l
  28.                                 (append (cdr l) '(()))
  29.                         )
  30.                  )
  31.                )
  32.                ")"
  33.        )
  34.      )
  35.    )
  36.     (vl-string->list str)
  37.   )
  38. )
Good good study , day day up . Sorry about my Chinglish .

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: Split String To Strings and Numbers
« Reply #6 on: October 02, 2017, 11:40:00 AM »
Thanks fools, works as expected!

More impressive is the single iteration you did, as I had to additionally process my string-list output into list of strings and numbers.
The returns in yours are slightly different, but overall suits my needs:
Code - Auto/Visual Lisp: [Select]
  1. _$ (LM:splitstring-F1 "Hi123SplitThis12.345String25-20")
  2. ("Hi" 123 "SplitThis" 12.345 "String" 25 "-" 20)
  3.  
  4. _$ (LM:splitstring-F1 "Hi.123SplitThis12.345String25-20")
  5. ("Hi." 123 "SplitThis" 12.345 "String" 25 "-" 20)
  6.  
  7. _$ (LM:splitstring-F1 "Hi..123SplitThis12.345String25-20")
  8. ("Hi.." 123 "SplitThis" 12.345 "String" 25 "-" 20)

Code: [Select]
;; Modified by Fools , 2011.10.2Is it really from 2011 ? I was really googling hard and couldn't find something like this.
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

VovKa

  • Water Moccasin
  • Posts: 1628
  • Ukraine
Re: Split String To Strings and Numbers
« Reply #7 on: October 02, 2017, 12:02:02 PM »
Code: [Select]
(LM:SPLITSTRING-F1 "a1")

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Split String To Strings and Numbers
« Reply #8 on: October 02, 2017, 12:42:46 PM »
For what it's worth (idea fodder) I wrote these ages ago. That said, the intent was to break out integers and delims from text (specifially filenames at the time), not reals. Don't have time at present to play with the latter as fun as that would be.

Code: [Select]
(defun _Rupture ( text )
    ;;  © 2017 Michael Puckett
    ;;  (_Rupture "X911.02-3C-0001.dwg")
    ;;  >> ("X" "911" "." "02" "-" "3" "C" "-" "0001" "." "dwg")
    (   (lambda ( f1 f2 l / x r )
            (foreach i (setq x (list (car l)) l (cdr l))
                (if (f1 i x)
                    (setq x (cons i x))
                    (setq r (cons x r) x (list i))
                )
            )
            (mapcar 'vl-list->string (cons x r))
        )
        (lambda (i x) (eq (f2 i) (f2 (car x))))
        (lambda (i) (cond ((or (< 64 i 91) (< 96 i 123)) 2) ((< 47 i 58) 1) ((< 32 i 128) 3) ((< -1 i 33) 0) (i 4)))
        (reverse (vl-string->list text))
    )
)

Code: [Select]
(defun _Fission ( text )
    ;;  © 2017 Michael Puckett
    ;;  (_Fission "X911.02-3C-0001.dwg")
    ;;  >> ("X" 911 "." 2 "-" 3 "C" "-" 1 "." "dwg")
    (   (lambda ( white )
            (mapcar
                (function (lambda (s) (if (wcmatch s "#*") (read s) (vl-string-trim white s))))
                (_Rupture text)
            )
        )
        (strcat " " (chr 160) "\n\r\t")
    )
)

Cheers.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: Split String To Strings and Numbers
« Reply #9 on: October 02, 2017, 03:44:06 PM »

Code: [Select]
(LM:SPLITSTRING-F1 "a1")

You are good at spotting eventual problems, guess I'll stick to mine version untill figuring out the fix for fool's modification.



For what it's worth (idea fodder) I wrote these ages ago.

Thanks for your input, Michael!

That said, the intent was to break out integers and delims from text (specifially filenames at the time), not reals.

I'm not sure whats the proper kind of labeling (only integers? no negatives?) when using alphanumerical strings - guess that depends on the company's standards.
I don't have current task to manipulate such strings (but theres always a first time) and thought that having such subfunction would be very useful.

Don't have time at present to play with the latter as fun as that would be.

Thats sad, also it seems that Lee is also busy (haven't been active in a while in the recent topics).
But I thought leaving the thread for the future, when anyone got free time.. (overall I'm leaving ideas in different threads here and there..).
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

fools

  • Newt
  • Posts: 72
  • China
Re: Split String To Strings and Numbers
« Reply #10 on: October 02, 2017, 08:54:21 PM »
Code: [Select]
(LM:SPLITSTRING-F1 "a1")

Code: [Select]
;; Modified by Fools , 2011.10.2Is it really from 2011 ? I was really googling hard and couldn't find something like this.

I rewritten the wrong code, and corrected the modification time.  :grinwink:

Code - Auto/Visual Lisp: [Select]
  1. ;; Split String  -  Lee Mac
  2. ;; Splits a string into a list of text and numbers
  3. ;; Modified by Fools , 2017.10.3
  4. ;; (LM:splitstring-F2 "Hi.123SplitThis12.345String25-20")
  5. ;; ("Hi" 0.123 "SplitThis" 12.345 "String" 25 "-" 20)
  6. (defun LM:splitstring-F2 (str)
  7.   ((lambda (l)
  8.      (read
  9.        (strcat "("
  10.                (vl-list->string
  11.                  (apply 'append
  12.                         (mapcar (function (lambda (a b c)
  13.                                             (cond ((= 92 b) (list 32 34 92 b 34 32)) ;_\
  14.                                                   ((< 47 b 58)  (list b)) ;_num
  15.                                                   ((and (= 46 b) (< 47 c 58)) (if (< 47 a 58) (list b) (list 34 48 b))) ;_.
  16.                                                   ((cond ((not a) ;_begin
  17.                                                           (if (< 47 c 58)
  18.                                                             (list 34 b 34)
  19.                                                             (list 34 b)
  20.                                                           )
  21.                                                          )
  22.                                                          ((not c) ;_end
  23.                                                           (if (< 47 a 58)
  24.                                                             (list 34 b 34)
  25.                                                             (list b 34)
  26.                                                           )
  27.                                                          )
  28.                                                          ((and (< 47 a 58) (< 47 c 58)) (list 34 b 34))
  29.                                                          ((< 47 a 58) (list 34 b))
  30.                                                          ((< 47 c 58) (list b 34))
  31.                                                          ((list b))
  32.                                                    )
  33.                                                   )
  34.                                             )
  35.                                           )
  36.                                 )
  37.                                 (cons nil l)
  38.                                 l
  39.                                 (append (cdr l) '(()))
  40.                         )
  41.                  )
  42.                )
  43.                ")"
  44.        )
  45.      )
  46.    )
  47.     (vl-string->list str)
  48.   )
  49. )


_$ (LM:splitstring-F2 "Hi.123SplitThis12.345String25-20")
("Hi" 0.123 "SplitThis" 12.345 "String" 25 "-" 20)
_$ (LM:splitstring-F2 "Hi123SplitThis12.345String25-20")
("Hi" 123 "SplitThis" 12.345 "String" 25 "-" 20)
_$ (LM:splitstring-F2 "Hi.123SplitThis12.345String25-20")
("Hi" 0.123 "SplitThis" 12.345 "String" 25 "-" 20)
_$ (LM:splitstring-F2 "Hi..123SplitThis12.345String25-20")
("Hi." 0.123 "SplitThis" 12.345 "String" 25 "-" 20)
_$ (LM:splitstring-F2 "a1")
("a" 1)
_$ (LM:splitstring-F2 "1a")
(1 "a")
Good good study , day day up . Sorry about my Chinglish .

VovKa

  • Water Moccasin
  • Posts: 1628
  • Ukraine
Re: Split String To Strings and Numbers
« Reply #11 on: October 03, 2017, 05:36:48 AM »
Code: [Select]
(LM:splitstring-F2 "a")

JohnK

  • Administrator
  • Seagull
  • Posts: 10626
Re: Split String To Strings and Numbers
« Reply #12 on: October 03, 2017, 09:06:03 AM »
lol!

I've written a few parsers (in C and C++) and they are very fun. I had to put my last compiler project aside because it was generating a nasty segfault somewhere in my real's parsing I just couldn't track down.

I've been looking at the code of that function "LM:splitstring.." and I somewhat understand it (at a high level) and it is approaching the problem in the same way as I would (in lisp) -i.e. operating on char codes but I'd be tempted to use a recursive type function in this instance (not a loop or a map function). Of course recursion will not get you real detection (or at least an efficient one) but, you may be able to handle a few of the special cases easier. A recursive method--in this application--has inherent problems vs a loop/map type function but you may need to weigh the good's and bad's of each different type against the specific case at hand.

Sorry, that post wasn't worth much but I was just trying to add to the conversation.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

ribarm

  • Gator
  • Posts: 3258
  • Marko Ribar, architect
Re: Split String To Strings and Numbers
« Reply #13 on: October 03, 2017, 09:58:00 AM »
Code: [Select]
(LM:splitstring-F2 "a")

Code - Auto/Visual Lisp: [Select]
  1. ;; Split String  -  Lee Mac
  2. ;; Splits a string into a list of text and numbers
  3. ;; Modified by Fools , 2017.10.3
  4. ;; (LM:splitstring-F2 "Hi.123SplitThis12.345String25-20")
  5. ;; ("Hi" 0.123 "SplitThis" 12.345 "String" 25 "-" 20)
  6. (defun LM:splitstring-F2 ( str )
  7.   ( (lambda ( l )
  8.       (read
  9.         (strcat
  10.           "("
  11.           (vl-list->string
  12.             (apply
  13.               (function append)
  14.                 (mapcar
  15.                   (function
  16.                     (lambda ( a b c )
  17.                       (cond
  18.                         ( (and (not a) (not c) (< 47 b 58))
  19.                           (list b)
  20.                         ) ;_single num
  21.                         ( (and (not a) (not c))
  22.                           (list 34 b 34)
  23.                         ) ;_single string
  24.                         ( (= 92 b)
  25.                           (list 32 34 92 b 34 32)
  26.                         ) ;_\
  27.                         ( (< 47 b 58)
  28.                           (list b)
  29.                         ) ;_num
  30.                         ( (and (= 46 b) (< 47 c 58))
  31.                           (if (< 47 a 58)
  32.                             (list b)
  33.                             (list 34 48 b)
  34.                           )
  35.                         ) ;_.
  36.                         ( (cond
  37.                             ( (not a) ;_begin
  38.                               (if (< 47 c 58)
  39.                                 (list 34 b 34)
  40.                                 (list 34 b)
  41.                               )
  42.                             )
  43.                             ( (not c) ;_end
  44.                               (if (< 47 a 58)
  45.                                 (list 34 b 34)
  46.                                 (list b 34)
  47.                               )
  48.                             )
  49.                             ( (and (< 47 a 58) (< 47 c 58))
  50.                               (list 34 b 34)
  51.                             )
  52.                             ( (< 47 a 58)
  53.                               (list 34 b)
  54.                             )
  55.                             ( (< 47 c 58)
  56.                               (list b 34)
  57.                             )
  58.                             ( (list b) )
  59.                           )
  60.                         )
  61.                       )
  62.                     )
  63.                   )
  64.                   (cons nil l)
  65.                   l
  66.                   (append (cdr l) '(()))
  67.                 )
  68.             )
  69.           )
  70.           ")"
  71.         )
  72.       )
  73.     )
  74.     (vl-string->list str)
  75.   )
  76. )
  77.  
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

VovKa

  • Water Moccasin
  • Posts: 1628
  • Ukraine
Re: Split String To Strings and Numbers
« Reply #14 on: October 03, 2017, 11:13:32 AM »

 :-)
Code: [Select]
(LM:splitstring-F2 "\\")

ribarm

  • Gator
  • Posts: 3258
  • Marko Ribar, architect
Re: Split String To Strings and Numbers
« Reply #15 on: October 03, 2017, 11:50:36 AM »
I am not  :devilsidesmile:
I'll just exclude all not valid strings and among them is your one...

Code - Auto/Visual Lisp: [Select]
  1. ;; Split String  -  Lee Mac
  2. ;; Splits a string into a list of text and numbers
  3. ;; Modified by Fools , 2017.10.3
  4. ;; Modified by MR , 2017.10.3
  5. ;; (LM:splitstring-F3 "Hi.123SplitThis12.345String25-20")
  6. ;; ("Hi" 0.123 "SplitThis" 12.345 "String" 25 "-" 20)
  7. (defun LM:splitstring-F3 ( str )
  8.   (if (snvalid str)
  9.     (read
  10.       ( (lambda ( l )
  11.           (strcat
  12.             "("
  13.             (vl-list->string
  14.               (apply
  15.                 (function append)
  16.                   (mapcar
  17.                     (function
  18.                       (lambda ( a b c )
  19.                         (cond
  20.                           ( (and (not a) (not c) (< 47 b 58))
  21.                             (list b)
  22.                           ) ;_single num
  23.                           ( (and (not a) (not c) (= 92 b))
  24.                             (list 34 92 b 34)
  25.                           ) ;_single \
  26.                           ( (and (not a) (not c))
  27.                             (list 34 b 34)
  28.                           ) ;_single alpha
  29.                           ( (= 92 b)
  30.                             (list 34 92 b 34)
  31.                           ) ;_\
  32.                           ( (< 47 b 58)
  33.                             (list b)
  34.                           ) ;_num
  35.                           ( (and (= 46 b) (< 47 c 58))
  36.                             (if (< 47 a 58)
  37.                               (list b)
  38.                               (list 34 48 b)
  39.                             )
  40.                           ) ;_.
  41.                           ( (cond
  42.                               ( (not a) ;_begin
  43.                                 (if (< 47 c 58)
  44.                                   (list 34 b 34)
  45.                                   (list 34 b)
  46.                                 )
  47.                               )
  48.                               ( (not c) ;_end
  49.                                 (if (< 47 a 58)
  50.                                   (list 34 b 34)
  51.                                   (list b 34)
  52.                                 )
  53.                               )
  54.                               ( (and (< 47 a 58) (< 47 c 58))
  55.                                 (list 34 b 34)
  56.                               )
  57.                               ( (< 47 a 58)
  58.                                 (list 34 b)
  59.                               )
  60.                               ( (< 47 c 58)
  61.                                 (list b 34)
  62.                               )
  63.                               ( (list b) )
  64.                             )
  65.                           )
  66.                         )
  67.                       )
  68.                     )
  69.                     (cons nil l)
  70.                     l
  71.                     (append (cdr l) '(()))
  72.                   )
  73.               )
  74.             )
  75.             ")"
  76.           )
  77.         )
  78.         (vl-string->list str)
  79.       )
  80.     )
  81.     (progn
  82.       (princ "\nSpecified string is not valid...")
  83.       (princ)
  84.     )
  85.   )
  86. )
  87.  
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: Split String To Strings and Numbers
« Reply #16 on: October 03, 2017, 03:47:19 PM »
Nice work, Marko!

Code - Auto/Visual Lisp: [Select]
  1. _$ (LM:splitstring-F3 "Hi123SplitThis12.345String25-20")
  2. ("Hi" 123 "SplitThis" 12.345 "String" 25 "-" 20)
  3.  
  4. _$ (LM:splitstring-F3 "Hi.123SplitThis12.345String25-20")
  5. ("Hi" 0.123 "SplitThis" 12.345 "String" 25 "-" 20)
  6.  
  7. _$ (LM:splitstring-F3 "Hi..123SplitThis12.345String25-20")
  8. ("Hi." 0.123 "SplitThis" 12.345 "String" 25 "-" 20)

Just a minor changes I would do:

Change
Code - Auto/Visual Lisp: [Select]
  1. (if (snvalid str)
To:
Code - Auto/Visual Lisp: [Select]
  1. (if (and (eq 'STR (type str)) (snvalid str))
 
Change
Code - Auto/Visual Lisp: [Select]
  1.   (princ "\nSpecified string is not valid...")
  2.   (princ)
  3. )
To:
Code - Auto/Visual Lisp: [Select]
  1. (prompt "\nSpecified string is not valid...")


Looks like alot of conditionals are going on.  :woow:
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: Split String To Strings and Numbers
« Reply #17 on: October 03, 2017, 04:33:07 PM »
I've been looking at the code of that function "LM:splitstring.." and I somewhat understand it (at a high level) and it is approaching the problem in the same way as I would (in lisp) -
i.e. operating on char codes
I'd say more impressive is the idea of supplying 3 arguments, say they represent (<Previous> <Current> <Next>) characters(string atoms)
and then theres the not-so-easy conditional part to investigate when to group/split (by operating with chr codes like you mentioned).

but I'd be tempted to use a recursive type function in this instance (not a loop or a map function).
I guess that the big conditional part might be the reason for this. (as I understood conditionals and recursions go together like socks'n'shoes).

Of course recursion will not get you real detection (or at least an efficient one) but, you may be able to handle a few of the special cases easier.
A recursive method--in this application--has inherent problems vs a loop/map type function but you may need to weigh the good's and bad's of each different type against the specific case at hand.
As long one does not deal with nested lists/arrays I don't see any difference between recursion and iteration - since one does not need to dig more than the 1st level.
In this case we're just proccessing a single string so.. its not that hard to translate that code to recursive type (see below code).
Or maybe I misunderstood what you ment?

Sorry, that post wasn't worth much but I was just trying to add to the conversation.
Appreciated, I like this forum because most users involve into discussions to solve/understand problems and not just copy/pasting codes.



Code - Auto/Visual Lisp: [Select]
  1. _$ (RecursiveSplitString "Hi123SplitThis12.345String25-20")
  2. ("Hi" 123 "SplitThis" 12.345 "String" 25 "-" 20)
  3.  
  4. _$ (RecursiveSplitString "Hi.123SplitThis12.345String25-20")
  5. ("Hi" 0.123 "SplitThis" 12.345 "String" 25 "-" 20)
  6.  
  7. _$ (RecursiveSplitString "Hi..123SplitThis12.345String25-20")
  8. ("Hi." 0.123 "SplitThis" 12.345 "String" 25 "-" 20)


Code - Auto/Visual Lisp: [Select]
  1. (defun RecursiveSplitString ( str / rec L )
  2.   ;; https://www.theswamp.org/index.php?topic=53496.0
  3.   ;; Based on Lee's (LM:splitstring) function and the following modifications:
  4.   ;; Modified by Fools , 2017.10.3
  5.   ;; Modified by MR , 2017.10.3
  6.   (defun rec ( L / a b c )
  7.     (mapcar 'set '(a b c) (list (car L) (cadr L) (caddr L)))
  8.     (cond
  9.       ( (vl-every 'null (list a b c)) nil)
  10.       (
  11.         (cons
  12.           (cond
  13.             ( (and (not a) (not c) (< 47 b 58))
  14.               (list b)
  15.             ) ;_single num
  16.             ( (and (not a) (not c) (= 92 b))
  17.               (list 34 92 b 34)
  18.             ) ;_single \
  19.             ( (and (not a) (not c))
  20.               (list 34 b 34)
  21.             ) ;_single alpha
  22.             ( (= 92 b)
  23.               (list 34 92 b 34)
  24.             ) ;_\
  25.             ( (< 47 b 58)
  26.               (list b)
  27.             ) ;_num
  28.             ( (and (= 46 b) (< 47 c 58))
  29.               (if (< 47 a 58)
  30.                 (list b)
  31.                 (list 34 48 b)
  32.               )
  33.             ) ;_.
  34.             (
  35.               (cond
  36.                 ( (not a) ;_begin
  37.                   (if (< 47 c 58)
  38.                     (list 34 b 34)
  39.                     (list 34 b)
  40.                   )
  41.                 )
  42.                 ( (not c) ;_end
  43.                   (if (< 47 a 58)
  44.                     (list 34 b 34)
  45.                     (list b 34)
  46.                   )
  47.                 )
  48.                 ( (and (< 47 a 58) (< 47 c 58))
  49.                   (list 34 b 34)
  50.                 )
  51.                 ( (< 47 a 58)
  52.                   (list 34 b)
  53.                 )
  54.                 ( (< 47 c 58)
  55.                   (list b 34)
  56.                 )
  57.                 ( (list b) )
  58.               )
  59.             )
  60.           ); cond
  61.           (rec (cdr L))
  62.         ); append
  63.       )
  64.     )
  65.   ); defun rec
  66.  
  67.   (cond
  68.     ( (not (eq 'STR (type str))) (prompt "\nNo string supplied.") )
  69.     ( (not (snvalid str)) (prompt "\nInvalid string supplied.") )
  70.     ( (setq L (rec (cons nil (vl-string->list str))))
  71.       (vl-remove '"" (read (strcat "(" (vl-list->string (vl-remove 'nil (apply 'append L))) ")")))
  72.     )
  73.   ); cond
  74.  
  75. ); defun RecursiveSplitString
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

VovKa

  • Water Moccasin
  • Posts: 1628
  • Ukraine
Re: Split String To Strings and Numbers
« Reply #18 on: October 03, 2017, 05:06:26 PM »
I am not  :devilsidesmile:
I'll just exclude all not valid strings and among them is your one...
one more :)
Code: [Select]
(LM:splitstring-F3 ".1")

p.s.
snvalid is too restrictive to be used with simple strings

fools

  • Newt
  • Posts: 72
  • China
Re: Split String To Strings and Numbers
« Reply #19 on: October 03, 2017, 11:58:15 PM »
Code: [Select]
(LM:splitstring-F2 "a")
Code: [Select]
(LM:splitstring-F2 "\\")
Code: [Select]
(LM:splitstring-F3 ".1")

The function is used to "split" a string into a list of text and numbers. If all are characters or only have numbers, maybe check it out before call this function will be better.

Code - Auto/Visual Lisp: [Select]
  1. ;; Split String  -  Lee Mac
  2. ;; Splits a string into a list of text and numbers
  3. ;; Modified by Fools , 2017.10.3
  4. ;; Modified by MR , 2017.10.3
  5. ;; Modified by Fools , 2017.10.4
  6. ;; (LM:splitstring-F4 "Hi.123SplitThis12.345String25-20")
  7. ;; ("Hi" 0.123 "SplitThis" 12.345 "String" 25 "-" 20)
  8. (defun LM:splitstring-F4 (str)
  9.   (cond ((distof str) (list (distof str))) ;_check all are numbers(put it out of the function maybe better)
  10.         ((wcmatch str "?") (list str)) ;_one char(put it out of the function maybe better)
  11.         ((read
  12.            ((lambda (l)
  13.               (strcat "("
  14.                       (vl-list->string
  15.                         (apply 'append
  16.                                (mapcar (function (lambda (a b c)
  17.                                                    (cond ((= 92 b) (list 32 34 92 b 34 32)) ;_ \
  18.                                                          ((< 47 b 58) (list b)) ;_ num
  19.                                                          ((and (= 46 b) (< 47 c 58))  ;_ dot
  20.                                                           (cond ((not a) (list 48 b)) ;_ dot is first char
  21.                                                                 ((< 47 a 58) (list b))
  22.                                                                 ((list 34 48 b))
  23.                                                           )
  24.                                                          )
  25.                                                          ((cond ((not a) ;_ begin
  26.                                                                  (if (< 47 c 58)
  27.                                                                    (list 34 b 34)
  28.                                                                    (list 34 b)
  29.                                                                  )
  30.                                                                 )
  31.                                                                 ((not c) ;_ end
  32.                                                                  (if (< 47 a 58)
  33.                                                                    (list 34 b 34)
  34.                                                                    (list b 34)
  35.                                                                  )
  36.                                                                 )
  37.                                                                 ((and (< 47 a 58) (< 47 c 58)) (list 34 b 34))
  38.                                                                 ((< 47 a 58) (list 34 b))
  39.                                                                 ((< 47 c 58) (list b 34))
  40.                                                                 ((list b))
  41.                                                           )
  42.                                                          )
  43.                                                    )
  44.                                                  )
  45.                                        )
  46.                                        (cons nil l)
  47.                                        l
  48.                                        (append (cdr l) '(()))
  49.                                )
  50.                         )
  51.                       )
  52.                       ")"
  53.               )
  54.             )
  55.              (vl-string->list str)
  56.            )
  57.          )
  58.         )
  59.   )
  60. )
« Last Edit: October 04, 2017, 12:28:03 AM by fools »
Good good study , day day up . Sorry about my Chinglish .

VovKa

  • Water Moccasin
  • Posts: 1628
  • Ukraine
Re: Split String To Strings and Numbers
« Reply #20 on: October 04, 2017, 05:23:02 AM »
The function is used to "split" a string into a list of text and numbers. If all are characters or only have numbers, maybe check it out before call this function will be better.
but distof will return float
(LM:splitstring-F4 "1")

there is one more thing i want to pay attention to (i'm not saying it's an error):
(setq a 1.) is OK
(setq a .1) is error
but your function returns the opposite (LM:splitstring-F4 "a1.b.1")

fools

  • Newt
  • Posts: 72
  • China
Re: Split String To Strings and Numbers
« Reply #21 on: October 04, 2017, 07:50:34 AM »
I don't think "LM:splitstring-F5" is better than the past, because more operations on the decimal point will reduce efficiency.
It's difficult to obtain strings such as "1." or ".1", unless it is intended.
Normally, it's almost impossible to encounter a decimal point not between two numbers.

Code - Auto/Visual Lisp: [Select]
  1. ;; Split String  -  Lee Mac
  2. ;; Splits a string into a list of text and numbers
  3. ;; Modified by Fools , 2017.10.3
  4. ;; Modified by MR , 2017.10.3
  5. ;; Modified by Fools , 2017.10.4
  6. ;;  (LM:splitstring-F5 ".1 .2ab2.cd.211dca234.")
  7. ;; (0.1 " " 0.2 "ab" 2.0 "cd" 0.211 "dca" 234.0)
  8. (defun LM:splitstring-F5 (str)
  9.   (cond ((distof str) ;_numbers (put it out of the function maybe better)
  10.          (if (vl-string-search "." str)
  11.            (list (distof str))
  12.            (list (atoi str))
  13.          )
  14.         )
  15.         ((= (strlen str) 1) (list str)) ;_one char(put it out of the function maybe better)
  16.         ((read ((lambda (l)
  17.                   (strcat "("
  18.                           (vl-list->string
  19.                             (apply 'append
  20.                                    (mapcar (function (lambda (a b c)
  21.                                                        (cond ((= 92 b) (list 32 34 92 b 34 32)) ;_ \
  22.                                                              ((< 47 b 58) (list b)) ;_ num
  23.                                                              ((not a) ;_ begin
  24.                                                               (if (< 47 c 58)
  25.                                                                 (if (= 46 b) ;_dot
  26.                                                                   (list 48 b)
  27.                                                                   (list 34 b 34)
  28.                                                                 )
  29.                                                                 (list 34 b)
  30.                                                               )
  31.                                                              )
  32.                                                              ((not c) ;_ end
  33.                                                               (if (< 47 a 58)
  34.                                                                 (if (= 46 b)
  35.                                                                   (list b 48)
  36.                                                                   (list 34 b 34)
  37.                                                                 )
  38.                                                                 (list b 34)
  39.                                                               )
  40.                                                              )
  41.                                                              ((and (< 47 a 58) (< 47 c 58))
  42.                                                               (if (= 46 b)
  43.                                                                 (list b)
  44.                                                                 (list 34 b 34)
  45.                                                               )
  46.                                                              )
  47.                                                              ((< 47 c 58)
  48.                                                               (if (= 46 b)
  49.                                                                 (list 34 48 b)
  50.                                                                 (list b 34)
  51.                                                               )
  52.                                                              )
  53.                                                              ((< 47 a 58)
  54.                                                               (if (= 46 b)
  55.                                                                 (list b 48 34)
  56.                                                                 (list 34 b)
  57.                                                               )
  58.                                                              )
  59.                                                              ((list b))
  60.                                                        )
  61.                                                      )
  62.                                            )
  63.                                            (cons nil l)
  64.                                            l
  65.                                            (append (cdr l) '(()))
  66.                                    )
  67.                             )
  68.                           )
  69.                           ")"
  70.                   )
  71.                 )
  72.                  (vl-string->list str)
  73.                )
  74.          )
  75.         )
  76.   )
  77. )

_$  (LM:splitstring-F5 ".1 .2ab2.cd.211dca234.")
(0.1 " " 0.2 "ab" 2.0 "cd" 0.211 "dca" 234.0)
_$  (LM:splitstring-F5 "1")
(1)
_$  (LM:splitstring-F5 "1.")
(1.0)
_$  (LM:splitstring-F5 ".1")
(0.1)
_$  (LM:splitstring-F5 ".1 2.")
(0.1 " " 2.0)
_$  (LM:splitstring-F5 ".12.")
(0)   error...
Good good study , day day up . Sorry about my Chinglish .

Lee Mac

  • Seagull
  • Posts: 12912
  • London, England
Re: Split String To Strings and Numbers
« Reply #22 on: October 07, 2017, 05:55:43 AM »
A bit late to the party...

To offer another approach, below is the function that I use as part of my Incremental Array program:
Code - Auto/Visual Lisp: [Select]
  1. (defun incarray:splitstring ( str / lst )
  2.     (setq lst (vl-string->list str))
  3.     (read (vl-list->string (vl-list* 40 34 (incarray:split lst (< 47 (car lst) 58)))))
  4. )
  5. (defun incarray:split ( lst flg )
  6.     (cond
  7.         (   (null lst) '(34 41))
  8.         (   (member (car lst) '(34 92))
  9.             (if flg
  10.                 (vl-list* 34 32 34 92 (car lst) (incarray:split (cdr lst) nil))
  11.                 (vl-list* 92 (car lst) (incarray:split (cdr lst) flg))
  12.             )
  13.         )
  14.         (   (or (< 47 (car lst) 58) (and (= 46 (car lst)) flg (< 47 (cadr lst) 58)))
  15.             (if flg
  16.                 (vl-list* (car lst) (incarray:split (cdr lst) flg))
  17.                 (vl-list* 34 32 34 (car lst) (incarray:split (cdr lst) t))
  18.             )
  19.         )
  20.         (   flg (vl-list* 34 32 34 (car lst) (incarray:split (cdr lst) nil)))
  21.         (   (vl-list* (car lst) (incarray:split (cdr lst) nil)))
  22.     )
  23. )

This could also be written iteratively:
Code - Auto/Visual Lisp: [Select]
  1. (defun LM:splitstring ( str )
  2.     (
  3.         (lambda ( l / f )
  4.             (read
  5.                 (strcat "(\""
  6.                     (vl-list->string
  7.                         (apply 'append
  8.                             (mapcar
  9.                                 (function
  10.                                     (lambda ( a b c )
  11.                                         (cond
  12.                                             (   (member b '(34 92))
  13.                                                 (if f
  14.                                                     (progn (setq f nil) (list 34 32 34 92 b))
  15.                                                     (list 92 b)
  16.                                                 )
  17.                                             )
  18.                                             (   (or (< 47 b 58) (and (= 46 b) f (< 47 c 58)))
  19.                                                 (if (or f (not a))
  20.                                                     (progn (setq f t) (list b))
  21.                                                     (progn (setq f t) (list 34 32 34 b))
  22.                                                 )
  23.                                             )
  24.                                             (   f
  25.                                                 (setq f nil)
  26.                                                 (list 34 32 34 b)
  27.                                             )
  28.                                             (   (list b))
  29.                                         )
  30.                                     )
  31.                                 )
  32.                                 (cons nil l) l (append (cdr l) '(( )))
  33.                             )
  34.                         )
  35.                     )
  36.                     "\")"
  37.                 )
  38.             )
  39.         )
  40.         (vl-string->list str)
  41.     )
  42. )

Code - Auto/Visual Lisp: [Select]
  1. _$ (LM:splitstring "Hi123SplitThis12.345String25-20")
  2. ("Hi" "123" "SplitThis" "12.345" "String" "25" "-" "20")
  3. _$ (LM:splitstring "1\"2")
  4. ("1" "\"" "2")
  5. _$ (LM:splitstring "1\\2")
  6. ("1" "\\" "2")

In my opinion, converting the numerical items from strings to numbers would limit the uses of this function in some cases, as information is lost during the conversion process. My original 'Split String' function was used as part of a sorting function in which the loss of such information was unimportant, but given an application such as my Incremental Array program, converting the string data at the parsing stage would lose leading & trailing zeros.
« Last Edit: October 07, 2017, 06:00:08 AM by Lee Mac »

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: Split String To Strings and Numbers
« Reply #23 on: October 07, 2017, 12:59:41 PM »
A bit late to the party...

Welcome - good to see you again! :)
So I guess that your iterative version behaves like this one (String->ListOfStringsAndNumbers), well without this extra proccessing in the end:
 
Code - Auto/Visual Lisp: [Select]
  1.  (setq r
  2.     (mapcar
  3.       (function
  4.         (lambda (x / n)
  5.           (cond
  6.             ( (= "." x) )
  7.             ( (wcmatch x "`.*")
  8.               (setq n (read (strcat "0" x)))
  9.             )
  10.             ( (setq n (read x)) )
  11.           )
  12.           (cond
  13.             ( (numberp n) n)
  14.             (x)
  15.           ); cond
  16.         ); lambda
  17.       ); function
  18.       (read
  19.         (strcat "("
  20.           (apply 'strcat L)
  21.           ")"
  22.         )
  23.       )
  24.     )
  25.   )
The hard part was to include this within the main iteration as fools and Marko were attempting.
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: Split String To Strings and Numbers
« Reply #24 on: December 23, 2017, 05:19:40 PM »
I know this thread is getting old, but I've just attempted this - and seems to work well:
Code - Auto/Visual Lisp: [Select]
  1. ; _$ (SplitStrToStrAndNumbers "Simple split examp73")
  2. ; >> ("Simple" "split" "examp" 73)
  3.  
  4. ; _$ (SplitStrToStrAndNumbers "Extract 123,4 These Lucky56 Num7 ber89,0s.532 ,42 .")
  5. ; >> ("Extract" 123.4 "These" "Lucky" 56 "Num" 7 "ber" 89.0 "s." 532 " ,42" " .")
  6.  
  7. ; _$ (SplitStrToStrAndNumbers "Split123,4This String56 In7o L1s7,0 of 57.r1ngs and n.895s .1 ,1")
  8. ; >> ("Split" 123.4 "This" "String" 56 "In" 7 "o" "L" 1 "s" 7.0 "of" 57.0 "r" 1 "ngs" "and" "n." 895 "s" " .1" " ,1") ; <- if theres no integer/zero infront of the "." - it won't be treated as decimal
  9.  
  10. ; _$ (SplitStrToStrAndNumbers "Split123,4This String56 In7o L1s7,0 of 57.r1ngs and n0.895 0.1 0,1")
  11. ; >> ("Split" 123.4 "This" "String" 56 "In" 7 "o" "L" 1 "s" 7.0 "of" 57.0 "r" 1 "ngs" "and" "n" 0.895 0.1 0.1)
  12.  
  13. ; _$ (SplitStrToStrAndNumbers "Theres 1. week and 1 day till 31/12/2017, so that makes 192,3 hours and 0.5 minutes.")
  14. ; >> ("Theres" 1.0 "week" "and" 1 "day" "till" 31 "/" 12 "/" 2017.0 "so" "that" "makes" 192.3 "hours" "and" 0.5 "minutes.")
  15. (defun SplitStrToStrAndNumbers ( str / rgx mc2 tmp tmp2 L )
  16.   ; https://www.theswamp.org/index.php?topic=53496.15
  17.   ; Split a string into a list of strings and numbers, using regular expressions
  18.   ; Credits: M.Puckett, Lee Mac, Roy
  19.   ;| Attempts:  
  20.   \d*[\.,]\d*|\d*|$  
  21.   [^\d\s]*[^\d\s]|\d*[\.,]\d*|\d*|$  
  22.   \d*[\.,]\d*|[^\d\s]*[^\d\s]|\d*|$  
  23.   \d*[\.,]\d*|(?:[^A-Z_a-z])[.,]\d*|[^\d\s]*[^\d\s]|\d*|$
  24.   |;
  25.   (vl-catch-all-apply
  26.     (function
  27.       (lambda nil
  28.         (setq rgx (vlax-get-or-create-object "vbscript.regexp"))
  29.         (vlax-put-property rgx 'global     actrue)
  30.         (vlax-put-property rgx 'ignorecase actrue)
  31.         (vlax-put-property rgx 'multiline  actrue)
  32.         (vlax-put-property rgx 'pattern    "\\d*[\\.,]\\d*|(?:[^A-Z_a-z])[.,]\\d*|[^\\d\\s]*[^\\d\\s]|\\d*|$") ; I used " " as delimeter (not sure if I wanted tho)
  33.         (vlax-for o (setq mc2 (vlax-invoke-method rgx 'Execute str))
  34.           (cond
  35.             ( (= "" (setq tmp (vlax-get-property o 'Value))) )
  36.             ( (progn (setq tmp2 (vl-catch-all-apply 'read (list (vl-string-subst "." "," tmp)))) nil) )
  37.             ( (setq L (cons (cond ( (or (vl-catch-all-error-p tmp2) (eq 'SYM (type tmp2))) tmp) (tmp2)) L)) )
  38.           ); cond
  39.         ); vlax-for
  40.       ); lambda
  41.     ); function
  42.   ); vl-catch-all-apply
  43.   (vl-catch-all-apply 'vlax-release-object (list rgx)) (reverse L)
  44. ); defun SplitStrToStrAndNumbers

Accreditation to the guys that introduced me into regex (getting started) - Although I'm still learning, so there might be bugs.
« Last Edit: December 23, 2017, 05:24:29 PM by Grrr1337 »
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

Dlanor

  • Bull Frog
  • Posts: 263
Re: Split String To Strings and Numbers
« Reply #25 on: March 09, 2018, 06:02:12 PM »
Just spotted this. I have noticed you're mixing your decimal seperators between "." and ",". Would this happen in the real world?

Here's my quick go based on my parse numbers routine. Apologies for the code formatting, it's straight out of Notepad++
Code: [Select]
(defun rh:regexp ( pattern t_str n_str b1 b2 / regex result matches m_lst rtn)
(if (and (< b2 5) (/= b2 3) (< b1 8))
(progn
(setq regex (vlax-create-object "VBScript.RegExp")
m_lst nil
);_end setq
(vlax-put-property regex 'Pattern pattern)
(if (not b1) (setq b1 0))
(if (/= 0 (boole 1 b1 4)) (vlax-put-property regex 'Multiline :vlax-true)) ;if set TRUE caret and dollar will match each line
(if (/= 0 (boole 1 b1 2)) (vlax-put-property regex 'IgnoreCase :vlax-true)) ;if set TRUE will perform a case-insensitive search
(if (/= 0 (boole 1 b1 1)) (vlax-put-property regex 'Global :vlax-true)) ;if set TRUE = find all matches False = first match

;; Replace Method
(if (/= 0 (boole 1 b2 4))
(progn
(setq result (vlax-invoke-method regex 'Replace t_str n_str))
(vlax-release-object regex)
(setq rtn result)
);_end progn
);_end if

;; Test Method
(if (/= 0 (boole 1 b2 1)) 
(progn
(setq result (vlax-invoke-method regex 'Test t_str))
(vlax-release-object regex)
(setq rtn result)
);_end progn
);_end if

;; Returns a list of matching sub strings if any
(if (/= 0 (boole 1 b2 2))
(progn
(setq matches (vlax-invoke-method regex 'Execute t_str))
(vlax-release-object regex)
(if (> (vlax-get-property matches 'Count) 0)
(progn
(vlax-for item matches
(setq m_lst (cons (vlax-get-property item 'Value) m_lst))
);_end for
(setq rtn (reverse m_lst))
);_end progn
(setq rtn nil)
);_end if
);_end progn
);_end if
);_end progn
);_end if
);_end defun (rh:regexp)


(defun c:test ( / txt r_lst n_lst)
(setq txt "There's 1. week and 1 day till 31/12/2017, so that makes 192.3 hours and 0.5 minutes.")
(setq r_lst (rh:regexp "[^0-9\. ]+|[0-9\.]+" txt "" 3 2))
(if (listp r_lst)
(setq n_lst (mapcar '(lambda (x y) (if (> (atof x) 0) (setq x (if (vl-string-search "." x) (atof x) (atoi x))) (setq x y ))) r_lst r_lst))
)
(princ "\n\n")
(princ n_lst)
)

;;>> ("There's" 1.0 "week" "and" 1 "day" "till" 31 "/" 12 "/" 2017 "," "so" "that" "makes" 192.3 "hours" "and" 0.5 "minutes" ".")


This won't parse numbers in scientific notation i.e. 1.23456E12, and I'm not sure whether you need the spurious punctuation?

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: Split String To Strings and Numbers
« Reply #26 on: March 09, 2018, 07:17:21 PM »
Just spotted this. I have noticed you're mixing your decimal seperators between "." and ",". Would this happen in the real world?

In almost all countries of Europe the standard for decimal separator is "," [ISO].
Although there are cases where "." is used and its still accepted, but rather uncommon to use it.
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

Dlanor

  • Bull Frog
  • Posts: 263
Re: Split String To Strings and Numbers
« Reply #27 on: March 10, 2018, 04:22:18 AM »
Quote
In almost all countries of Europe the standard for decimal separator is "," [ISO].
Although there are cases where "." is used and its still accepted, but rather uncommon to use it.

I'm aware of that, my point was that the test string contains both "." & "," in locations that indicate they are being used as decimal separators. Any single string of text should be consistant, otherwise your heaping complexity onto a simple function.

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: Split String To Strings and Numbers
« Reply #28 on: March 10, 2018, 05:49:27 AM »
my point was that the test string contains both "." & "," in locations that indicate they are being used as decimal separators.
Any single string of text should be consistant, otherwise your heaping complexity onto a simple function.

I agree that the text should be consistant, but that doesn't mean it would be - so it doesn't apply on all cases where the #main is used.
For instance:
  • split text patterns from two different projects and compare the values (one uses "." the other ",")
  • split an existing text pattern that breaks the 'consistant rule' (the project was done n-years ago, and you can't trace the author to blame him)
  • use that subfunction within iteration to process n amount of different strings (some use "," other ".")

So I'd rather make it a bit complex, than forcing myself to re-work the correct regex pattern when I'd be short on time.
Ofcourse this problem shouldn't apply to countries like USA if everyone follows the ANSI standard for dot decimal separator.

BTW mentioned from here why you are not passing the literal character, so your regex pattern fails (it splits "Word.AnotherWord") :
Code - Auto/Visual Lisp: [Select]
  1. _$ (SplitStrToStrAndNumbers "Spl.it1.2 thi.s56")                >> ("Spl.it" 1.2 "thi.s" 56)
  2. _$ (rh:regexp "[^0-9\. ]+|[0-9\.]+" "Spl.it1.2 thi.s56" "" 3 2) >> ("Spl" "." "it" "1.2" "thi" "." "s" "56")
  3.  
  4.  
  5. _$ (SplitStrToStrAndNumbers "Word.AnotherWord") >> ("Word.AnotherWord")
  6. _$ (rh:regexp "[^0-9\. ]+|[0-9\.]+" "Word.AnotherWord" "" 3 2) >> ("Word" "." "AnotherWord")

- I still remember MP's valuable advice.
« Last Edit: March 10, 2018, 05:53:44 AM by Grrr1337 »
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

Dlanor

  • Bull Frog
  • Posts: 263
Re: Split String To Strings and Numbers
« Reply #29 on: March 10, 2018, 01:02:26 PM »
BTW mentioned from here why you are not passing the literal character, so your regex pattern fails (it splits "Word.AnotherWord") :

Which literal character? The regex used was a quick adaptation of a regex used to extract integer and real numbers from a text string.

I have adapted the regex and incorporated some look forwards.
Code: [Select]
(rh:regexp "[0-9\.]+|(?:[A-Za-z\.(?!\d)\/(?=\d)]+)|[\,]" txt "" 3 2)


txt = Spl.it1.2 thi.s56
 >> ("Spl.it" 1.2 "thi.s" 56)

txt = Word.AnotherWord 
>> ("Word.AnotherWord")

txt = "Theres 1. week and 1 day till 31/12/2017, so that makes 192.3 hours and 0.5 minutes."
>> ("Theres" 1.0 "week" "and" 1 "day" "till" 31 "/" 12 "/" 2017 "," "so" "that" "makes" 192.3 "hours" "and" 0.5 "minutes.")

I'm not sure in the last string whether the comma (",") after 2017 is used as a decimal separator or a comma. I've assumed comma as it makes more sense when you read it.

Lee Mac

  • Seagull
  • Posts: 12912
  • London, England
Re: Split String To Strings and Numbers
« Reply #30 on: March 10, 2018, 05:39:11 PM »
@Dlanor, note that the backslash is an escape character in AutoLISP, hence you will need to double-up the backslashes in your string for the backslash to appear in the RegEx pattern - working with RegEx in AutoLISP tends to suffer from Leaning Toothpick Syndrome :D

Lee

Dlanor

  • Bull Frog
  • Posts: 263
Re: Split String To Strings and Numbers
« Reply #31 on: March 10, 2018, 10:20:01 PM »
@Dlanor, note that the backslash is an escape character in AutoLISP, hence you will need to double-up the backslashes in your string for the backslash to appear in the RegEx pattern - working with RegEx in AutoLISP tends to suffer from Leaning Toothpick Syndrome :D

Hmmm..  WYSIWYG..  The shown regexp pattern produced the displayed results. If I double up the backslashes in the pattern it doesn't. Maybe it's my setup (AC2009 64 on Win 8.1) or, out on a limb, perhaps VB2010 Express.

Dlanor

  • Bull Frog
  • Posts: 263
Re: Split String To Strings and Numbers
« Reply #32 on: March 11, 2018, 07:43:15 AM »
Hmmm..  WYSIWYG..  The shown regexp pattern produced the displayed results. If I double up the backslashes in the pattern it doesn't. Maybe it's my setup (AC2009 64 on Win 8.1) or, out on a limb, perhaps VB2010 Express.

My apologies, the above doesn't hold true on my desktop (AC2012 64 on Win 7). There i need to double up the backslashes.  :wideeyed:

Wierd... I'm also now talking to myself  :idiot2: :2funny:

Ok, laptop problem, reboot and sfc throws some errors. Restoring from last good image.
« Last Edit: March 11, 2018, 08:05:33 AM by Dlanor »

Dlanor

  • Bull Frog
  • Posts: 263
Re: Split String To Strings and Numbers
« Reply #33 on: March 11, 2018, 01:02:42 PM »
This will tell you what the decimal separator is on the system

Code: [Select]
(setq d_sep (vl-registry-read "HKEY_USERS\\.DEFAULT\\Control Panel\\International" "sDecimal"))

Using the Replace Method, this regex and replacement string will return the inserted string with all instances of (digit,digit) replaced with (digit.digit)

Code: [Select]
"(\\d),(\\d)"  "$1.$2"