quotes, double quotes, parenthesis will not pass through read function
;; Modified by Fools , 2011.10.2
Is it really from 2011 ? I was really googling hard and couldn't find something like this.
(LM:SPLITSTRING-F1 "a1")
(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))
)
)
(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")
)
)
Code: [Select](LM:SPLITSTRING-F1 "a1")
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](LM:SPLITSTRING-F1 "a1")
Code: [Select];; Modified by Fools , 2011.10.2
Is it really from 2011 ? I was really googling hard and couldn't find something like this.
(LM:splitstring-F2 "a")
Code: [Select](LM:splitstring-F2 "a")
(LM:splitstring-F2 "\\")
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'd say more impressive is the idea of supplying 3 arguments, say they represent (<Previous> <Current> <Next>) characters(string atoms)
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).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.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.
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.Appreciated, I like this forum because most users involve into discussions to solve/understand problems and not just copy/pasting codes.
I am not :devilsidesmile:one more :)
I'll just exclude all not valid strings and among them is your one...
(LM:splitstring-F3 ".1")
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.but distof will return float
A bit late to the party...
(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" ".")
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.
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.
BTW mentioned from here (http://www.theswamp.org/index.php?topic=53990.msg586374#msg586374) why you are not passing the literal character, so your regex pattern fails (it splits "Word.AnotherWord") :
(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.")
@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 (https://en.wikipedia.org/wiki/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.
(setq d_sep (vl-registry-read "HKEY_USERS\\.DEFAULT\\Control Panel\\International" "sDecimal"))
"(\\d),(\\d)" "$1.$2"