The problem about making one LARGE info-string is, well its size.
I've tried this Kind of solution, when I first wrote getInfo. Basically lining up all red out entities to one sting. The problem here was the limitation given by the hardware. The process ate... devoured a large amount of ram and CPU capacity, causing it to slow down drastically. I'll try your solution but I have a bad feeling bout it. I should also mention, it's not the getInfo function itself, who writes to the file, it's every single get[entity type] who does that.
Code: [Select](setq dStr (strcat "INSERT" spcr)
dStr (strcat dStr entLay spcr)
dStr (strcat dStr entName spcr)
dStr (strcat dStr entX spcr entY spcr entZ spcr)
dStr (strcat dStr entScaX spcr)
dStr (strcat dStr entScaY spcr)
dStr (strcat dStr entScaZ spcr)
dStr (strcat dStr entRot spcr)
dStr (strcat dStr entNormStr "\n")
)
...Very interesting, thanks.
See the attached file for some general tips on optimizing
string-related operations.
(defun string->list (s delim)
(read
(vl-list->string
(append
'(40 34) ;; add '("' to start
(apply 'append
(subst
'(34 34)
(vl-string->list delim)
(mapcar 'list (vl-string->list s))
)
)
'(34 41) ;; add '")" to end
)
)
)
)
(string->list "\"Abc\",\"123\"" ",") => ("" ABC "" "" 123 ""); Version 1.00 - November 2001
;
; Description:
; convert a string into a list
;
; Arguments:
; InpStr = string [STR]
; CarDlm = delimiter [STR] 1 character
;
(defun ALE_String2List (InpStr CarDlm / SttPos EndPos TmpLst)
(setq
CarDlm (ascii CarDlm) SttPos 0
EndPos (vl-string-position CarDlm InpStr)
)
(while EndPos
(setq
TmpLst (cons (substr InpStr (1+ SttPos) (- EndPos SttPos)) TmpLst)
SttPos (1+ EndPos) EndPos (vl-string-position CarDlm InpStr SttPos)
)
)
(reverse (cons (substr InpStr (1+ SttPos)) TmpLst))
)
(defun string->list (s delim)
(read
(vl-list->string
(append
'(40 34) ;; add '("' to start
(apply 'append
(subst
'(34 34)
(vl-string->list delim)
(subst
'(92 34)
'(34)
(mapcar 'list (vl-string->list s))
)
)
)
'(34 41) ;; add '")" to end
)
)
)
)
Command: (string->list "\"Abc\",\"123\"" ",")
("\"Abc\"" "\"123\"")
About speed, also I have modified your code to:
(setq string->list-slow ALE_String2List)
Comando: TEST_STRING_TO_LIST
Generating test data...
Working...
Test data string length: 348893
Result list length: 10000
Average of 6 median iterations:
(string->list-slow): 0.034
(string->list-fast): 0.5613
(string-split "\t\tabc,123\n xyz,456" "\n,\t ")
=> ("abc" "123" "xyz" "456")
(string-split "x=10,y=25,z=0" '("," "="))
=> (("x" "10") ("y" "25") ("z" "0"))
Code: [Select]; Version 1.00 - November 2001
;
; Description:
; convert a string into a list
;
; Arguments:
; InpStr = string [STR]
; CarDlm = delimiter [STR] 1 character
;
(defun ALE_String2List (InpStr CarDlm / SttPos EndPos TmpLst)
(setq
CarDlm (ascii CarDlm) SttPos 0
EndPos (vl-string-position CarDlm InpStr)
)
(while EndPos
(setq
TmpLst (cons (substr InpStr (1+ SttPos) (- EndPos SttPos)) TmpLst)
SttPos (1+ EndPos) EndPos (vl-string-position CarDlm InpStr SttPos)
)
)
(reverse (cons (substr InpStr (1+ SttPos)) TmpLst))
)
Command: (setq str "552.32,\"Smith, John\",42,350")
"552.32,\"Smith, John\",42,350"
Command: (ale_string2list str ",")
("552.32" "\"Smith" " John\"" "42" "350")
Command: (string-parse str ",")
("552.32" "\"Smith, John\"" "42" "350")
(defun string-parse ( s delimiters / dquote ddquote flag )
(cond
( (not delimiters) s)
( (vl-consp delimiters)
(mapcar
(function
(lambda (str)
(string-parse str (cdr delimiters))
)
)
(string-parse s (car delimiters))
)
)
(t (setq dquote '(92 34))
(setq ddquote '(34 34))
(read
(vl-list->string
(append
'(40 34)
(apply 'append
(mapcar
(function
(lambda (c)
(cond
;; escape double-quote and toggle flag
( (eq c 34)
(setq flag (not flag))
dquote
)
;; if flag is set, ignore delimiters:
(flag (list c))
;; replace delimiter with 2 double-quotes
( (vl-string-position c delimiters) ddquote)
(t (list c))
)
)
)
(vl-string->list s)
)
)
'(34 41)
)
)
)
)
)
)
<clip>Thank Tony for your complete and accurate answer.
Again, this was only minimally-tested with your example, and I don't know if it works in every case
<clip>Tony,
; John Uhden, Cadlantic/formerly CADvantage
; String2List
; Originally ALE_STRING2LIST By Marc'Antonio Alessi
; Date: Thursday, November 08, 2001
;
; Renamed in:
; Function: ALE_String2ListStrDlm
;
; Version 1.00
;
; Description:
; convert a string into a list
;
; Arguments:
; InpStr = string [STR]
; CarDlm = delimiter > 1 or more characters [STR]
;
; Examples:
; (ALE_String2ListStrDlm "\"Abc\"][1.0][1][Xyz" "][")
; => ("\"Abc\"" "1.0" "1" "Xyz")
; (ALE_String2ListStrDlm "\"Abc\"][1.0][1][Xyz][(][99" "][")
; => ("\"Abc\"" "1.0" "1" "Xyz" "(" "99")
; (ALE_String2ListStrDlm "\"Abc\"][1.0][1][Xyz][)][99" "][")
; => ("\"Abc\"" "1.0" "1" "Xyz" ")" "99")
; (ALE_String2ListStrDlm "\"Abc\"][1.0][1][Xyz][\"][99" "][")
; => ("\"Abc\"" "1.0" "1" "Xyz" "\"" "99")
; (ALE_String2ListStrDlm "\"Abc\"][1.0][1][Xyz][,][99" "][")
; => ("\"Abc\"" "1.0" "1" "Xyz" "," "99")
; (ALE_String2ListStrDlm "\"Abc\"][1.0][1][Xyz][.][99" "][")
; => ("\"Abc\"" "1.0" "1" "Xyz" "." "99")
; (ALE_String2ListStrDlm "\"Abc\"][1.0][1][Xyz][.99" "][")
; => ("\"Abc\"" "1.0" "1" "Xyz" ".99")
;
; Return Values:
; [LIST]
;
(defun ALE_String2ListStrDlm (InpStr StrDlm / SttPos TmpPos DlmLng TmpLst)
(cond
( (/= (type InpStr) (type StrDlm) 'STR) )
( (= InpStr StrDlm) '("") )
(T
(setq
DlmLng (strlen StrDlm) SttPos 0
TmpPos (vl-string-search StrDlm InpStr SttPos)
)
(while TmpPos
(setq
TmpLst (cons (substr InpStr (1+ SttPos) (- TmpPos SttPos)) TmpLst)
SttPos (+ TmpPos DlmLng)
TmpPos (vl-string-search StrDlm InpStr SttPos)
)
)
(reverse (cons (substr InpStr (1+ SttPos)) TmpLst))
)
)
)
; Marc'Antonio Alessi, Italy - http://xoomer.virgilio.it/alessi
;
; Function: ALE_String_ToList
;
; Version 1.00 - 01/2010
;
; Description:
; convert a string into a list of strings
;
; Arguments:
; InpStr = string [STR]
; CarDlm = delimiter [STR] 1 character
; TrueFl = if nil remove dupes delimiter
;
; Examples:
; (ALE_String_ToList "aaa_vvv_hhh__yyy ___lll_" "_" T)
; ("aaa" "vvv" "hhh" "" "yyy " "" "" "lll" "lll")
;
; (ALE_String_ToList "aaa_vvv_hhh__yyy ___lll_" "_" nil)
; ("aaa" "vvv" "hhh" "yyy " "lll")
;
(defun ALE_String_ToList (InpStr CarDlm TrueFl / SttPos EndPos TmpLst TmpStr)
(setq
CarDlm (ascii CarDlm) SttPos 0
EndPos (vl-string-position CarDlm InpStr)
)
(while EndPos
(setq
TmpStr (substr InpStr (1+ SttPos) (- EndPos SttPos))
SttPos (1+ EndPos) EndPos (vl-string-position CarDlm InpStr SttPos)
)
(and
(or (/= TmpStr "") TrueFl)
(setq TmpLst (cons TmpStr TmpLst))
)
)
(if (or (/= (setq TmpStr (substr InpStr (1+ SttPos))) "") TrueFl)
(reverse (cons TmpStr TmpLst))
(reverse TmpLst)
)
)
<clip>The correct result should have 4 elements:<clip>Tony, see my previous:
<clip>The correct result should have 4 elements:<clip>Tony, see my previous:
>>> (string-parse) is the function which the string->list
>>> example function from that document was based on.
>>> It was designed from the outset to parse CDF-formatted
>>> data, where commas that appear between two double-quotes
>>> are interpreted as literal text content, rather than
>>> as delimiters.
Very correct, now I will try to write a new version for this ;-)
Maybe tomorrow :|
Happy Easter.
Marco
Code - Text: [Select]
Command: (setq result (string-parse str ",")) ("552.32" "\"Smith, John\"" "42" "350") Command: (length result) 4
(defun cdf->lst ( str / sub )
(
(setq sub
(lambda ( str pos / tmp )
(cond
( (not (setq pos (vl-string-position 44 str pos)))
(list str)
)
( (wcmatch (setq tmp (substr str 1 pos)) "\"*[~\"]")
(sub str (+ pos 2))
)
( (cons tmp (sub (substr str (+ pos 2)) 0)))
)
)
)
str 0
)
)
_$ (setq str "552.32,\"Smith, John\",42,350")
"552.32,\"Smith, John\",42,350"
_$ (cdf->lst str)
("552.32" "\"Smith, John\"" "42" "350")
(defun cdf->lst-i1 ( str / f )
(read
(vl-list->string
(append '(40 34)
(apply 'append
(mapcar
(function
(lambda ( x )
(cond
( (and (= 44 x) (not f))
'(34 34)
)
( (= 34 x)
(setq f (not f))
'(92 34)
)
( (list x) )
)
)
)
(vl-string->list str)
)
)
'(34 41)
)
)
)
)
(defun cdf->lst-i2 ( str / r f )
(setq r '(34 41))
(foreach x (reverse (vl-string->list str))
(cond
( (and (= 44 x) (not f))
(setq r (vl-list* 34 34 r))
)
( (= 34 x)
(setq f (not f)
r (vl-list* 92 34 r)
)
)
( (setq r (cons x r)))
)
)
(read (vl-list->string (vl-list* 40 34 r)))
)
I guess an iterative solution using vl-string->list could be something like:Code: [Select](defun cdf->lst-i1 ( str / f )
(read
(vl-list->string
(append '(40 34)
(apply 'append
(mapcar
(function
(lambda ( x )
(cond
( (and (= 44 x) (not f))
'(34 34)
)
( (= 34 x)
(setq f (not f))
'(92 34)
)
( (list x) )
)
)
)
(vl-string->list str)
)
)
'(34 41)
)
)
)
)
Or perhaps:Code: [Select](defun cdf->lst-i2 ( str / r f )
(setq r '(34 41))
(foreach x (reverse (vl-string->list str))
(cond
( (and (= 44 x) (not f))
(setq r (vl-list* 34 34 r))
)
( (= 34 x)
(setq f (not f)
r (vl-list* 92 34 r)
)
)
( (setq r (cons x r)))
)
)
(read (vl-list->string (vl-list* 40 34 r)))
)
;; A version of (string-parse) that uses (vl-string-position) to find all
;; delimiters and double-quotes, properly ignoring delimiters contained in
;; literal text content surrounded by double-quotes.
(defun string-parse-revisited (str delim / ascdelim ascquote len indices qpos rslt)
(setq ascdelim (ascii delim) ascquote 34)
(if (not (setq indices (string-positions str ascdelim t)))
(list str)
(progn
(if (setq qpos (string-positions str ascquote nil))
(setq indices
(apply 'append
(mapcar
(function
(lambda (x)
(cond
( (eq (cdr x) 34)
(setq flag (not flag))
nil
)
( (not flag)
(list (car x))
)
)
)
)
(vl-sort
(append
(mapcar (function (lambda (i) (cons i ascdelim))) indices)
(mapcar (function (lambda (i) (cons i ascquote))) qpos)
)
(function (lambda (a b) (< (car a) (car b))))
)
)
)
)
)
(aggregate-binary indices
(function
(lambda (start end)
(substr str (1+ start) (- end start 1))
)
)
)
)
)
)
;; Returns the results of applying the the given
;; function to pairs of adjacent elements in the
;; given list.
(defun aggregate-binary (aggbin:lst aggbin:func / aggbin:rslt)
(while (cdr aggbin:lst)
(setq aggbin:rslt
(cons
(apply aggbin:func (list (car aggbin:lst) (cadr aggbin:lst)))
aggbin:rslt
)
aggbin:lst (cdr aggbin:lst)
)
)
(reverse aggbin:rslt)
)
;; Returns the indices required by (substr) for extracting
;; the text delimited by adjacent-pairs of delimiters. If
;; the extents argument is non-nil, 0/1+ the length of the
;; string are added to the start/end of the result list.
;; If the input string contains no delimiter characters,
;; the result is nil regardless of whether extents is non-
;; nil or not.
(defun string-positions (str char extents / p c res len )
(if (not (numberp char))
(setq c (ascii char))
(setq c char)
)
(setq len (strlen str))
(setq pos -1)
(while (setq pos (vl-string-position c str (1+ pos)))
(setq res (cons (1+ pos) res))
)
(if (and res extents (>= len (car res)))
(setq res (cons (1+ len) res))
)
(setq res (reverse res))
(if (and res extents (> (car res) 0))
(setq res (cons 0 res))
)
res
)
; minimal testing
(defun ALE_String_ToListDQ (InpStr CarDlm / SttPos EndPos TmpLst SttDQt EndDQt)
(setq
CarDlm (ascii CarDlm) SttPos 0
EndPos (vl-string-position CarDlm InpStr)
)
(if
(and
(setq SttDQt (vl-string-position 34 InpStr))
(setq EndDQt (vl-string-position 34 InpStr (1+ SttDQt)))
)
(progn
(while EndPos
(cond
( (and EndDQt (< SttDQt EndPos EndDQt))
(setq EndPos (vl-string-position CarDlm InpStr (1+ EndPos)))
)
( T
(setq
SttDQt (vl-string-position 34 InpStr (1+ EndPos))
TmpLst (cons (substr InpStr (1+ SttPos) (- EndPos SttPos)) TmpLst)
SttPos (1+ EndPos) EndPos (vl-string-position CarDlm InpStr SttPos)
)
(and SttDQt (setq EndDQt (vl-string-position 34 InpStr (1+ SttDQt))))
)
)
)
(reverse (cons (substr InpStr (1+ SttPos)) TmpLst))
)
(progn
(while EndPos
(setq
TmpLst (cons (substr InpStr (1+ SttPos) (- EndPos SttPos)) TmpLst)
SttPos (1+ EndPos) EndPos (vl-string-position CarDlm InpStr SttPos)
)
)
(reverse (cons (substr InpStr (1+ SttPos)) TmpLst))
)
)
)
Hi Marco.Hi Tony,
Very good.
CSV format allows contents of literal strings to also contain double-quotes, by using two consecutive double quotes, as in:
"a, b, c,\"John \"\"The Baptist\"\" Smith\",4,5,6"
Which should produce:
("a" "b" "c" "John \"The Baptist\" Smith" "4" "5" "6")
That problem is easily solved when processing each character (store the last-processed character, and if it is also a double-quote then treat it as literal content).
Comando: (setq str "a, b, c,\"John \"\"The Baptist\"\" Smith\",4,5,6")
"a, b, c,\"John \"\"The Baptist\"\" Smith\",4,5,6"
Comando: (ALE_String_ToListDQ str ",")
("a" " b" " c" "\"John \"\"The Baptist\"\" Smith\"" "4" "5" "6")
Comando: (setq str "a, b, c,John \"The Baptist\" Smith,4,5,6")
"a, b, c,John \"The Baptist\" Smith,4,5,6"
Comando: (ALE_String_ToListDQ str ",")
("a" " b" " c" "John \"The Baptist\" Smith" "4" "5" "6")
Comando: (setq str "552.32,\"Smith, John\",42,350,a,b,c,d")
"552.32,\"Smith, John\",42,350,a,b,c,d"
Comando: (ALE_String_ToListDQ str ",")
("552.32" "\"Smith, John\"" "42" "350" "a" "b" "c" "d")
New shorter version:
; Version 1.10 - 07-04-2013 - minimal testing
(defun ALE_String_ToListDQ (InpStr CarDlm / SttPos EndPos TmpLst SttDQt EndDQt)
(setq
CarDlm (ascii CarDlm) SttPos 0
EndPos (vl-string-position CarDlm InpStr)
SttDQt (vl-string-position 34 InpStr)
)
(and SttDQt (setq EndDQt (vl-string-position 34 InpStr (1+ SttDQt))))
(while EndPos
(cond
( (and EndDQt (< SttDQt EndPos EndDQt))
(setq EndPos (vl-string-position CarDlm InpStr (1+ EndPos)))
)
( T
(and SttDQt (setq SttDQt (vl-string-position 34 InpStr (1+ EndPos))))
(setq
TmpLst (cons (substr InpStr (1+ SttPos) (- EndPos SttPos)) TmpLst)
SttPos (1+ EndPos) EndPos (vl-string-position CarDlm InpStr SttPos)
)
(and SttDQt (setq EndDQt (vl-string-position 34 InpStr (1+ SttDQt))))
)
)
)
(reverse (cons (substr InpStr (1+ SttPos)) TmpLst))
)
On the topic of CSV parsing, this (http://lee-mac.com/readcsv.html) is what I use (accounting for both quotes & commas present in the cell data, and also allowing for alternative cell delimiter characters) though I make no claims for its efficiency.Lee,
On the topic of CSV parsing, this (http://lee-mac.com/readcsv.html) is what I use (accounting for both quotes & commas present in the cell data, and also allowing for alternative cell delimiter characters) though I make no claims for its efficiency.I'm sorry but I have some problems with the English language, I did not understand what you mean and where is your example.
"a, b, c,\"John \"\"The Baptist\"\" Smith\",4,5,6" is a correct CSV format?
"a, b, c,\"John \"\"The Baptist\"\" Smith\",4,5,6"
is indeed a valid CSV format. _$ (LM:csv->lst "a, b, c,\"John \"\"The Baptist\"\" Smith\",4,5,6" 44 0)
("a" " b" " c" "John \"The Baptist\" Smith" "4" "5" "6")
To demonstrate, try creating a CSV file with the above cell values and open the CSV file using a plain text editor._$ (mapcar '(lambda ( x ) (vl-string-trim " \t" x)) (LM:csv->lst "a, b, c,\"John \"\"The Baptist\"\" Smith\",4,5,6" 44 0))
("a" "b" "c" "John \"The Baptist\" Smith" "4" "5" "6")
Hi Marco.Hi Tony,
Very good.
CSV format allows contents of literal strings to also contain double-quotes, by using two consecutive double quotes, as in:
"a, b, c,\"John \"\"The Baptist\"\" Smith\",4,5,6"
Which should produce:
("a" "b" "c" "John \"The Baptist\" Smith" "4" "5" "6")
That problem is easily solved when processing each character (store the last-processed character, and if it is also a double-quote then treat it as literal content).
do not you think that the CSV format normally is: "a, b, c,John \"The Baptist\" Smith,4,5,6"
not "a, b, c,\"John \"\"The Baptist\"\" Smith\",4,5,6" ?Code: [Select]Comando: (setq str "a, b, c,\"John \"\"The Baptist\"\" Smith\",4,5,6")
"a, b, c,\"John \"\"The Baptist\"\" Smith\",4,5,6"
Comando: (ALE_String_ToListDQ str ",")
("a" " b" " c" "\"John \"\"The Baptist\"\" Smith\"" "4" "5" "6")
Comando: (setq str "a, b, c,John \"The Baptist\" Smith,4,5,6")
"a, b, c,John \"The Baptist\" Smith,4,5,6"
Comando: (ALE_String_ToListDQ str ",")
("a" " b" " c" "John \"The Baptist\" Smith" "4" "5" "6")
Comando: (setq str "552.32,\"Smith, John\",42,350,a,b,c,d")
"552.32,\"Smith, John\",42,350,a,b,c,d"
Comando: (ALE_String_ToListDQ str ",")
("552.32" "\"Smith, John\"" "42" "350" "a" "b" "c" "d")Code: [Select]New shorter version:
; Version 1.10 - 07-04-2013 - minimal testing
(defun ALE_String_ToListDQ (InpStr CarDlm / SttPos EndPos TmpLst SttDQt EndDQt)
(setq
CarDlm (ascii CarDlm) SttPos 0
EndPos (vl-string-position CarDlm InpStr)
SttDQt (vl-string-position 34 InpStr)
)
(and SttDQt (setq EndDQt (vl-string-position 34 InpStr (1+ SttDQt))))
(while EndPos
(cond
( (and EndDQt (< SttDQt EndPos EndDQt))
(setq EndPos (vl-string-position CarDlm InpStr (1+ EndPos)))
)
( T
(and SttDQt (setq SttDQt (vl-string-position 34 InpStr (1+ EndPos))))
(setq
TmpLst (cons (substr InpStr (1+ SttPos) (- EndPos SttPos)) TmpLst)
SttPos (1+ EndPos) EndPos (vl-string-position CarDlm InpStr SttPos)
)
(and SttDQt (setq EndDQt (vl-string-position 34 InpStr (1+ SttDQt))))
)
)
)
(reverse (cons (substr InpStr (1+ SttPos)) TmpLst))
)
OK Thanks.On the topic of CSV parsing, this (http://lee-mac.com/readcsv.html) is what I use (accounting for both quotes & commas present in the cell data, and also allowing for alternative cell delimiter characters) though I make no claims for its efficiency.I'm sorry but I have some problems with the English language, I did not understand what you mean and where is your example.
"a, b, c,\"John \"\"The Baptist\"\" Smith\",4,5,6" is a correct CSV format?
Sorry Marc, I should have explained further.
The string:Code: [Select]"a, b, c,\"John \"\"The Baptist\"\" Smith\",4,5,6"
is indeed a valid CSV format.
My CSV parsing function will then return the result:Code: [Select]_$ (LM:csv->lst "a, b, c,\"John \"\"The Baptist\"\" Smith\",4,5,6" 44 0)
To demonstrate, try creating a CSV file with the above cell values and open the CSV file using a plain text editor.
("a" " b" " c" "John \"The Baptist\" Smith" "4" "5" "6")
Note that my function does not remove whitespace between cell data as I wrote the function with the intention to return the exact CSV content; if whitespace should be removed, the above result may be processed using:Code: [Select]_$ (mapcar '(lambda ( x ) (vl-string-trim " \t" x)) (LM:csv->lst "a, b, c,\"John \"\"The Baptist\"\" Smith\",4,5,6" 44 0))
("a" "b" "c" "John \"The Baptist\" Smith" "4" "5" "6")
Sorry for the confusion.
Hi Marco. In an Excel sheet, enter this, including all the double-quotes:Tony,
"John "the baptist" Smith"
Save to CSV, and look at the output.
Hi Marco. In an Excel sheet, enter this, including all the double-quotes:Tony,
"John "the baptist" Smith"
Save to CSV, and look at the output.
"John "the baptist" Smith" it is very redundant!
Perhaps this is an acceptable result:
("a" " b" " c" "\"John \"\"The Baptist\"\" Smith\"" "4" "5" "6")
I go to sleep, good night.
If it doesn't handle the data correctly, than how fast it runs is meaningless.
; Version 1.11 - 09-04-2013
(defun ALE_String_ToListDQ (InpStr CarDlm / SttPos EndPos TmpLst TmpStr TmpPos SttDQt EndDQt TrueFl)
(setq
CarDlm (ascii CarDlm) SttPos 0
EndPos (vl-string-position CarDlm InpStr)
SttDQt (vl-string-position 34 InpStr)
)
(and SttDQt (setq EndDQt (vl-string-position 34 InpStr (1+ SttDQt))))
(while EndPos
(and
EndDQt
(= "\"" (substr InpStr (1+ EndDQt) 1)) (setq TrueFl T)
(setq EndDQt (vl-string-position 34 InpStr (+ 2 EndDQt)))
)
(cond
( (and EndDQt (< SttDQt EndPos EndDQt))
(setq EndPos (vl-string-position CarDlm InpStr (1+ EndPos)))
)
( T
(and SttDQt (setq SttDQt (vl-string-position 34 InpStr (1+ EndPos))))
(setq TmpStr (substr InpStr (1+ SttPos) (- EndPos SttPos)))
(and
TrueFl
(setq TmpPos 0)
(while (setq TmpPos (vl-string-search "\"\"" TmpStr TmpPos))
(setq TmpStr (vl-string-subst "\"" "\"\"" TmpStr TmpPos)
TmpPos (1+ TmpPos)
)
)
(setq TmpStr (vl-string-trim "\"" TmpStr) TrueFl nil)
)
(setq
TmpLst (cons TmpStr TmpLst)
SttPos (1+ EndPos) EndPos (vl-string-position CarDlm InpStr SttPos)
)
(and SttDQt (setq EndDQt (vl-string-position 34 InpStr (1+ SttDQt))))
)
)
)
(reverse (cons (substr InpStr (1+ SttPos)) TmpLst))
)
(ALE_String_ToListDQ "a, b, c,\"John \"\"The,Baptist\"\" Smith\",4,5,6" ",")
=> ("a" " b" " c" "John \"The,Baptist\" Smith" "4" "5" "6")
(setq str "\"Smith,John\",\"\"\"The Baptist\"\"\"")
("Smith,John" "\"The Baptist\"")
Try this Marc::-(Code: [Select](setq str "\"Smith,John\",\"\"\"The Baptist\"\"\"")
The result should be:Code: [Select]("Smith,John" "\"The Baptist\"")
:-)
Try this Marc::-(Code: [Select](setq str "\"Smith,John\",\"\"\"The Baptist\"\"\"")
The result should be:Code: [Select]("Smith,John" "\"The Baptist\"")
:-)
"\"Smith,John\",\"\"\"The Baptist\"\"\""
do you think this is a valid value?, can you post an image of the cell? like in:
http://www.theswamp.org/index.php?topic=40660.msg459469#msg459469
Grazie.
"\"Smith,John\",\"\"\"The Baptist\"\"\""
>> Providing the CSV delimiter is a comma, the above will yield a text value of: ...
I have modified my italian settings (also decimal sep.): "," ";" to "." ","
and now I can see.
Ah yes, the function also needs to account for the use of different CSV delimiters! :evil:May be we need to look the settings in Control Panel:
Ah yes, the function also needs to account for the use of different CSV delimiters! :evil:May be we need to look the settings in Control Panel:
Excel : Smith,John "The Baptist"
CSV italian settings : Smith,John;"""The Baptist"""
CSV english settings: "Smith,John","""The Baptist"""
Buona serata.
Comando: (setq str "\"abc,123\",\"\"\"ABC\"\"\",\"abc\"\"ABC\"\"123\"")
"\"abc,123\",\"\"\"ABC\"\"\",\"abc\"\"ABC\"\"123\""
Comando: (LM:csv->lst str 44 0)
("abc,123" "\"ABC\"" "abc\"ABC\"123")
Comando: (setq str "a, b, c,\"John \"\"The Baptist\"\" Smith\",4,5,6")
"a, b, c,\"John \"\"The Baptist\"\" Smith\",4,5,6"
Comando: (LM:csv->lst str 44 0)
("a" " b" " c" "John \"The Baptist\" Smith" "4" "5" "6")
Comando: (setq str "552.32,\"Smith, John\",42,350,a,b,c,d")
"552.32,\"Smith, John\",42,350,a,b,c,d"
Comando: (LM:csv->lst str 44 0)
("552.32" "Smith, John" "42" "350" "a" "b" "c" "d")
Comando: (setq str "\"Smith,John\",\"\"\"The Baptist\"\"\"")
"\"Smith,John\",\"\"\"The Baptist\"\"\""
Comando: (LM:csv->lst str 44 0)
("Smith,John" "\"The Baptist\"")
(defun ALE_StringSubstAll (NewStr PatStr InpStr SttPos / NewLen)
(cond
( (= "" PatStr) InpStr )
( (setq NewLen (strlen NewStr))
(while (setq SttPos (vl-string-search PatStr InpStr SttPos))
(setq
InpStr (vl-string-subst NewStr PatStr InpStr SttPos)
SttPos (+ SttPos NewLen)
)
)
InpStr
)
)
)
(defun ALE_String_CdfToList (InpStr CarDlm / SttPos EndPos TmpStr OutLst TmpElm)
(setq
CarDlm (ascii CarDlm) SttPos 0
EndPos (vl-string-position CarDlm InpStr)
)
(while EndPos
(cond
( (wcmatch (setq TmpElm (substr InpStr (1+ SttPos) (- EndPos SttPos))) "\"*\"")
(setq OutLst
(cons
(ALE_StringSubstAll "\"" "\"\"" (substr TmpElm 2 (- (strlen TmpElm) 2)) 0)
OutLst
)
)
)
( (wcmatch TmpElm "\"*") (setq TmpStr (substr TmpElm 2)) )
( TmpStr
(setq OutLst
(cons
(strcat TmpStr (chr CarDlm) (substr TmpElm 1 (- (strlen TmpElm) 1)))
OutLst
)
TmpStr nil
)
)
( T (setq OutLst (cons TmpElm OutLst)) )
)
(setq SttPos (1+ EndPos) EndPos (vl-string-position CarDlm InpStr SttPos))
)
(reverse
(cons
(cond
( (wcmatch (setq TmpElm (substr InpStr (1+ SttPos))) "\"*\"")
(ALE_StringSubstAll "\"" "\"\"" (substr TmpElm 2 (- (strlen TmpElm) 2)) 0)
)
( (wcmatch TmpElm "\"*")(setq TmpStr (substr TmpElm 2)) )
( TmpStr (strcat TmpStr (chr CarDlm) (substr TmpElm 1 (- (strlen TmpElm) 1))) )
( T TmpElm )
)
OutLst
)
)
)
(defun ALE_String_CdfToListFE (InpStr CarDlm / SttPos EndPos TmpLst TmpStr TmpPos OutLst)
(setq
CarDlm (ascii CarDlm) SttPos 0
EndPos (vl-string-position CarDlm InpStr)
)
(while EndPos
(setq
TmpLst (cons (substr InpStr (1+ SttPos) (- EndPos SttPos)) TmpLst)
SttPos (1+ EndPos) EndPos (vl-string-position CarDlm InpStr SttPos)
)
)
(foreach ForElm (cons (substr InpStr (1+ SttPos)) TmpLst)
(cond
( (wcmatch ForElm "\"*\"")
(setq TmpPos 0 ForElm (substr ForElm 2 (- (strlen ForElm) 2)))
(while (setq TmpPos (vl-string-search "\"\"" ForElm TmpPos))
(setq
ForElm (vl-string-subst "\"" "\"\"" ForElm TmpPos)
TmpPos (1+ TmpPos)
)
)
(setq OutLst (cons ForElm OutLst))
)
( (wcmatch ForElm "*\"")
(setq TmpStr (substr ForElm 1 (- (strlen ForElm) 1)))
)
( TmpStr
(setq OutLst
(cons
(strcat (substr ForElm 2) (chr CarDlm) TmpStr)
OutLst
)
TmpStr nil
)
)
( T (setq OutLst (cons ForElm OutLst)) )
)
)
OutLst
)
Comando: (setq str "\"abc,123\",\"\"\"ABC\"\"\",\"abc\"\"ABC\"\"123\"")
"\"abc,123\",\"\"\"ABC\"\"\",\"abc\"\"ABC\"\"123\""
Comando: (ALE_String_CdfToList str ",")
("abc,123" "\"ABC\"" "abc\"ABC\"123")
Comando: (ALE_String_CdfToListFE str ",")
("abc,123" "\"ABC\"" "abc\"ABC\"123")
Comando: (LM:csv->lst str 44 0)
("abc,123" "\"ABC\"" "abc\"ABC\"123")
Comando: (setq str "a, b, c,\"John \"\"The Baptist\"\" Smith\",4,5,6")
"a, b, c,\"John \"\"The Baptist\"\" Smith\",4,5,6"
Comando: (ALE_String_CdfToList str ",")
("a" " b" " c" "John \"The Baptist\" Smith" "4" "5" "6")
Comando: (ALE_String_CdfToListFE str ",")
("a" " b" " c" "John \"The Baptist\" Smith" "4" "5" "6")
Comando: (LM:csv->lst str 44 0)
("a" " b" " c" "John \"The Baptist\" Smith" "4" "5" "6")
Comando: (setq str "552.32,\"Smith, John\",42,350,a,b,c,d")
"552.32,\"Smith, John\",42,350,a,b,c,d"
Comando: (ALE_String_CdfToList str ",")
("552.32" "Smith, John" "42" "350" "a" "b" "c" "d")
Comando: (ALE_String_CdfToListFE str ",")
("552.32" "Smith, John" "42" "350" "a" "b" "c" "d")
Comando: (LM:csv->lst str 44 0)
("552.32" "Smith, John" "42" "350" "a" "b" "c" "d")
Comando: (setq str "\"Smith,John\",\"\"\"The Baptist\"\"\"")
"\"Smith,John\",\"\"\"The Baptist\"\"\""
Comando: (ALE_String_CdfToList str ",")
("Smith,John" "\"The Baptist\"")
Comando: (ALE_String_CdfToListFE str ",")
("Smith,John" "\"The Baptist\"")
Comando: (LM:csv->lst str 44 0)
("Smith,John" "\"The Baptist\"")
/[code]
; Version 1.01 - 11-04-2013
(defun ALE_String_CdfToList (InpStr CarDlm / SttPos EndPos TmpStr OutLst TmpElm)
(setq CarDlm (ascii CarDlm) SttPos 0 EndPos (vl-string-position CarDlm InpStr))
(while EndPos
(cond
( (wcmatch (setq TmpElm (substr InpStr (1+ SttPos) (- EndPos SttPos))) "\"*\"")
(setq OutLst (cons (ALE_StringSubstAll "\"" "\"\"" (substr TmpElm 2 (- (strlen TmpElm) 2)) 0) OutLst))
)
( (wcmatch TmpElm "\"*") (setq TmpStr (substr TmpElm 2)) )
( (= TmpElm "") (if TmpStr (setq TmpStr (strcat TmpStr ",")) (setq TmpStr ",")) )
( TmpStr
(setq
OutLst (cons (strcat TmpStr (chr CarDlm) (substr TmpElm 1 (- (strlen TmpElm) 1))) OutLst)
TmpStr nil
)
)
( T (setq OutLst (cons TmpElm OutLst)) )
)
(setq SttPos (1+ EndPos) EndPos (vl-string-position CarDlm InpStr SttPos))
)
(reverse
(cons
(cond
( (wcmatch (setq TmpElm (substr InpStr (1+ SttPos))) "\"*\"")
(ALE_StringSubstAll "\"" "\"\"" (substr TmpElm 2 (- (strlen TmpElm) 2)) 0)
)
( (wcmatch TmpElm "\"*")(setq TmpStr (substr TmpElm 2)) )
( TmpStr (strcat TmpStr (chr CarDlm) (substr TmpElm 1 (- (strlen TmpElm) 1))) )
( T TmpElm )
)
OutLst
)
)
)
Comando: (ALE_String_CdfToList "\"Smith,,,,,John\",123" ",")
("Smith,,,,,John" "123")
New version for problems with multiple separator: "\"Smith,,,,,John\",123"New version for other problems:
; Version 1.02 - 15-04-2013
(defun ALE_String_CdfToList (InpStr CarDlm / AscDlm SttPos EndPos TmpStr OutLst TmpElm)
(setq AscDlm (ascii CarDlm) SttPos 0 EndPos (vl-string-position AscDlm InpStr))
(while EndPos
(cond
( (wcmatch (setq TmpElm (substr InpStr (1+ SttPos) (- EndPos SttPos))) "\"*\"")
(setq OutLst (cons (ALE_StringSubstAll "\"" "\"\"" (substr TmpElm 2 (- (strlen TmpElm) 2)) 0) OutLst))
)
( (and (not TmpStr) (wcmatch TmpElm "\"*")) (setq TmpStr (substr TmpElm 2)) )
( TmpStr
(cond
( (= TmpElm "\"") (setq OutLst (cons (strcat TmpStr CarDlm) OutLst) TmpStr nil) )
( (wcmatch TmpElm "*\"")
(setq
OutLst (cons (strcat TmpStr CarDlm (substr TmpElm 1 (- (strlen TmpElm) 1))) OutLst)
TmpStr nil
)
)
( T (setq TmpStr (strcat TmpStr "," TmpElm)) )
)
)
( T (setq OutLst (cons TmpElm OutLst)) )
)
(setq SttPos (1+ EndPos) EndPos (vl-string-position AscDlm InpStr SttPos))
)
(reverse
(cons
(cond
( (wcmatch (setq TmpElm (substr InpStr (1+ SttPos))) "\"*\"")
(ALE_StringSubstAll "\"" "\"\"" (substr TmpElm 2 (- (strlen TmpElm) 2)) 0)
)
( (and (not TmpStr) (wcmatch TmpElm "\"*")) (substr TmpElm 2) )
( TmpStr
(cond
( (= TmpElm "\"") (strcat TmpStr CarDlm) )
( (wcmatch TmpElm "*\"") (strcat TmpStr CarDlm (substr TmpElm 1 (- (strlen TmpElm) 1))) )
( T (strcat TmpStr "," TmpElm) )
)
)
( T TmpElm )
)
OutLst
)
)
)
Comando: (ALE_String_CdfToList "\",Smith,,r,,,John,,\",123,\",fd,,ffd,\"" ",")
(",Smith,,r,,,John,," "123" ",fd,,ffd,")
Lee,
(setq str "\"Smith,John\",\"\"\"The Baptist\"\"\",\"abc\"\"The Baptist\"\"123\",\"acb\"\"\",\"\"\"123\"")
Comando: (LM:csv->lst str 44 0)
("Smith,John" "\"The Baptist\"" "abc\"The Baptist\"123" "acb\"\",\"\"123")
^^^^^
Thanks Marc, I'll investigate. 8-)
Result should be:Code - Auto/Visual Lisp: [Select]
("," ",," "\"" "\"\"" ",\"" "\",\"")Code - Auto/Visual Lisp: [Select]I guess it depends how far you wish to go with it... :|
_$ (LM:csv->lst str "," 0) ("," ",," "\"" "\"\"" ",\"" "\",\"") _$ (ALE_String_CdfToList str ",") ("," ",," "\"" "\"\"" "\"" "\"" "\"")
In the meantime I found another problem:
Comando: (LM:csv->lst "\"aaa," "," 0)
; errore: valore dell'argomento errato: string position out of range 6
My apologies Lee, I do not know if ("\"aaa,") is a valid CSV content, it came out doing some manual testing, delete my report.