Author Topic: Ignoring certain blocks on output  (Read 17335 times)

0 Members and 1 Guest are viewing this topic.

TheMaster

  • Guest
Re: Ignoring certain blocks on output
« Reply #15 on: March 30, 2013, 01:33:36 PM »
Marco - Prego.

Code - Text: [Select]
  1.  
  2. Command: (setq str "552.32,\"Smith, John\",42,350")
  3. "552.32,\"Smith, John\",42,350"
  4.  
  5. ;; correct CDF-parsing code must ignore the delimiter
  6. ;; between "Smith" and "John", because it appears between
  7. ;; double-quotes and must therefore be treated as literal
  8. ;; content.  The correct result should have 4 elements:
  9.  
  10. Command: (setq result (ale_string_tolist str "," t))
  11. ("552.32" "\"Smith" " John\"" "42" "350")
  12.  
  13. Command: (length result) 5
  14.  
  15. Command: (setq result (ale_string_tolist str "," nil))
  16. ("552.32" "\"Smith" " John\"" "42" "350")
  17.  
  18. Command: (length result) 5
  19.  
  20. Command: (setq result (ale_String2ListStrDlm str ","))
  21. ("552.32" "\"Smith" " John\"" "42" "350")
  22.  
  23. Command: (length result) 5
  24.  
  25. Command: (setq result (string-parse str ","))
  26. ("552.32" "\"Smith, John\"" "42" "350")
  27.  
  28. Command: (length result) 4
  29.  
  30.  

The actual working version I've not posted also removes extra whitespace characters from the input, which  makes for a more-interesting problem to solve using your approach. That was the underlying reason for my choosing to process the input character-by-character, rather than searching for delimiters and quotes using vl-string-position.

Of course nowadays, we can solve the same problem in managed C# in about 1/4 the time required by any of these LISP-based solutions.
« Last Edit: March 30, 2013, 01:54:07 PM by TT »

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: Ignoring certain blocks on output
« Reply #16 on: March 30, 2013, 01:59:18 PM »
<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

TheMaster

  • Guest
Re: Ignoring certain blocks on output
« Reply #17 on: March 30, 2013, 02:24:14 PM »
<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

Marco - Happy Easter.

This is somewhat difficult to do using vl-string-position approach, but if we also want to remove extra whitespace, then it comes close to "mission impossible" :laugh:

There are many published algorithms for parsing CDF-format data (most in C++), and pretty-much every one that I've seen must go character-by-character to solve the problem completely.

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: Ignoring certain blocks on output
« Reply #18 on: March 30, 2013, 07:54:44 PM »
Code - Text: [Select]
  1. Command: (setq result (string-parse str ","))
  2. ("552.32" "\"Smith, John\"" "42" "350")
  3.  
  4. Command: (length result) 4

This looked interesting to code, so here is my quick attempt:
Code: [Select]
(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
    )
)
Code: [Select]
_$ (setq str "552.32,\"Smith, John\",42,350")
"552.32,\"Smith, John\",42,350"
_$ (cdf->lst str)
("552.32" "\"Smith, John\"" "42" "350")

Though it certainly won't be too fast by its recursive nature.

TheMaster

  • Guest
Re: Ignoring certain blocks on output
« Reply #19 on: March 31, 2013, 03:25:59 AM »
Hi Lee.

Yes that works. The only concern I would have with using recursion in a problem case like this one, in terms of speed, is that each recursive call receives a copy of the string argument that's passed by the caller.

Code - Text: [Select]
  1.  
  2. Command: (setq str "552.32,\"Smith, John\",42,350,a,b,c,d")
  3. "552.32,\"Smith, John\",42,350,a,b,c,d"
  4.  
  5. Command: (trace sub)
  6. SUB
  7.  
  8. Command: (cdf->lst str)
  9. Entering (SUB "\"Smith, John\",42,350,a,b,c,d" 0)
  10.   Entering (SUB "\"Smith, John\",42,350,a,b,c,d" 8)
  11.     Entering (SUB "42,350,a,b,c,d" 0)
  12.       Entering (SUB "350,a,b,c,d" 0)
  13.         Entering (SUB "a,b,c,d" 0)
  14.           Entering (SUB "b,c,d" 0)
  15.             Entering (SUB "c,d" 0)
  16.               Entering (SUB "d" 0)
  17.               Result:  ("d")
  18.             Result:  ("c" "d")
  19.           Result:  ("b" "c" "d")
  20.         Result:  ("a" "b" "c" "d")
  21.       Result:  ("350" "a" "b" "c" "d")
  22.     Result:  ("42" "350" "a" "b" "c" "d")
  23.   Result:  ("\"Smith, John\"" "42" "350" "a" "b" "c" "d")
  24. Result:  ("\"Smith, John\"" "42" "350" "a" "b" "c" "d")
  25. ("552.32" "\"Smith, John\"" "42" "350" "a" "b" "c" "d")
  26.  
  27.  

In the above, even though the amount of data between each delimiters is relatively-small, each recursive call receives a copy of everything that remains, which would lead me to suspect that it may not be as fast as a simple iterative loop that operates on the list of ints returned by vl-string->list.

When doing classic recursion on a list, the only thing that gets copied is the cons cell for the CAR of the list, but with strings, each call requires a copy of the string to be made, which may bring us back to the main point I was making with my first post, the reason for avoiding numerous calls to (strcat).

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: Ignoring certain blocks on output
« Reply #20 on: March 31, 2013, 07:43:15 AM »
Good point Tony.

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)))
)

TheMaster

  • Guest
Re: Ignoring certain blocks on output
« Reply #21 on: March 31, 2013, 07:50:02 PM »
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)))
)

I was interested in trying to get Marco's approach to work with the problem case that I wrote string-parse to solve, and while I was able to get it to work for quoted delimiters, the other special handling of the input string is still a tough nut to crack, and I'm not really sure that it would be worth the effort.

These days, with most of my work done in .NET and C++, I surely wouldn't attempt to put a LISP-based solution into actual use, but trying to get a working implementation is still a fun exercise, and so (quickly hacked-up and with minimal testing):

Code: [Select]

;; 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
)


Code - Text: [Select]
  1.  
  2. Command: (setq str "552.32,\"Smith, John\",42,350,a,b,c,d")
  3. "552.32,\"Smith, John\",42,350,a,b,c,d"
  4.  
  5. Command: (string-parse-revisited str ",")
  6. ("552.32" "\"Smith, John\"" "42" "350" "a" "b" "c" "d")
  7.  
  8.  
« Last Edit: April 01, 2013, 06:19:12 AM by TT »

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: Ignoring certain blocks on output
« Reply #22 on: April 06, 2013, 01:37:48 PM »
Tony and Lee,

sorry for late, now recommend to the moderator to open a new thread
for part of the functions of string-parse.
Here is my original function adapted to work for quoted delimiters:
Code: [Select]
; 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))
    )
  )
)

Code - Text: [Select]
  1. Comando: (setq str "552.32,\"Smith, John\",42,350,a,b,c,d")
  2. "552.32,\"Smith, John\",42,350,a,b,c,d"
  3.  
  4. Comando: (ALE_String_ToListDQ str ",")
  5. ("552.32" "\"Smith, John\"" "42" "350" "a" "b" "c" "d")
  6.  

With StringBuildingTest.lsp I get this:
(setq string->list-slow ALE_String_ToListDQ)
(setq string->list-fast string-parse-revisited)

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.0262  >>> ALE_String_ToListDQ
  (string->list-fast): 0.1067  >>> string-parse-revisited

%%

(setq string->list-slow ALE_String_ToListDQ)
(setq string->list-fast cdf->lst-i2)

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.031  >>> ALE_String_ToListDQ
  (string->list-fast): 0.567  >>> cdf->lst-i2

(defun cdf->lst-i2 ( str foo / r f )...
>>> Modified with 2 arguments

TheMaster

  • Guest
Re: Ignoring certain blocks on output
« Reply #23 on: April 07, 2013, 11:09:31 AM »
Hi Marco.

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).

« Last Edit: April 07, 2013, 11:19:48 AM by TT »

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: Ignoring certain blocks on output
« Reply #24 on: April 07, 2013, 12:11:40 PM »
Hi Marco.

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).
Hi Tony,
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))
)

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: Ignoring certain blocks on output
« Reply #25 on: April 07, 2013, 12:19:58 PM »
On the topic of CSV parsing, this 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.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: Ignoring certain blocks on output
« Reply #26 on: April 07, 2013, 12:31:00 PM »
On the topic of CSV parsing, this 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,
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?

Thanks for your time.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: Ignoring certain blocks on output
« Reply #27 on: April 07, 2013, 12:41:53 PM »
Lee,

I tryed your function but I get error, where I am wrong?

(setq str  "a, b, c,John The Baptist Smith,4,5,6")
(LM:csv->lst str "," 0)
(setq str  "a, b, c,John \"The Baptist\" Smith,4,5,6")
(LM:csv->lst str "," 0)
(setq str "552.32,\"Smith, John\",42,350,a,b,c,d")
(LM:csv->lst str "," 0)

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: Ignoring certain blocks on output
« Reply #28 on: April 07, 2013, 02:38:08 PM »
On the topic of CSV parsing, this 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)
("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.

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.

TheMaster

  • Guest
Re: Ignoring certain blocks on output
« Reply #29 on: April 07, 2013, 03:09:06 PM »
Hi Marco.

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).
Hi Tony,
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))
)

Hi Marco.  In an Excel sheet, enter this, including all the double-quotes:

       "John "the baptist" Smith"

Save to CSV, and look at the output.