No edit summary |
(Added examples for CSV and white space delimited parsing) |
||
(17 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
− | '''Parse string (AutoLISP function)''' is a function to turn a delimited string, such as Comma Separated Values (CSV), Tab-delimited, or white space separated, into a list with one list element per string field. |
||
− | |||
− | ==Source code== |
||
− | {{AutoLISPheader}} |
||
<pre> |
<pre> |
||
;;;WIKI-STRTOLST |
;;;WIKI-STRTOLST |
||
Line 8: | Line 4: | ||
;;;Usage: (wiki-strtolst |
;;;Usage: (wiki-strtolst |
||
;;; [InputString containing fields] |
;;; [InputString containing fields] |
||
− | ;;; [FieldSeparatorWC field delimiter wildcard string |
+ | ;;; [FieldSeparatorWC field delimiter wildcard string |
+ | ;;; Use "`," for comma and " ,\t" for white space |
||
⚫ | |||
− | ;;; |
+ | ;;; ] |
⚫ | |||
;;; [EmptyFieldsDoCount flag. |
;;; [EmptyFieldsDoCount flag. |
||
;;; If nil, consecutive field delimiters are ignored. |
;;; If nil, consecutive field delimiters are ignored. |
||
Line 16: | Line 13: | ||
;;; ] |
;;; ] |
||
;;; ) |
;;; ) |
||
+ | ;;; Examples: |
||
+ | ;;; CSV (wiki-strtolst string "`," "\"" T) |
||
+ | ;;; Word delimited (wiki-strtolst string " ,\t,\n" "" nil) |
||
+ | ;;; Revision history |
||
+ | ;;; 2009-01-17 TGH Replaced test for empty fieldseparatorwc with a simple '= function |
||
+ | ;| |
||
+ | Edit the source code for this function at </pre> |
||
+ | [[strtolst (AutoLISP function)|http://autocad.wikia.com/wiki/Strtolst_(AutoLISP_function)]] |
||
⚫ | |||
+ | |; |
||
;;;Avoid cleverness. |
;;;Avoid cleverness. |
||
;;;Human readability trumps elegance and economy and cleverness here. |
;;;Human readability trumps elegance and economy and cleverness here. |
||
Line 22: | Line 29: | ||
;;;And I am trying a new commenting style. |
;;;And I am trying a new commenting style. |
||
;;;Tests |
;;;Tests |
||
− | ;;;(alert (apply 'strcat (mapcar '(lambda (x) (strcat "\n----\n" x)) (wiki-strtolst "1 John,\"2 2\"\" pipe,\nheated\",3 the end,,,,," "," "\"" nil)))) |
+ | ;;;(alert (apply 'strcat (mapcar '(lambda (x) (strcat "\n----\n" x)) (wiki-strtolst "1 John,\"2 2\"\" pipe,\nheated\",3 the end,,,,," "`," "\"" nil)))) |
− | ;;;(alert (apply 'strcat (mapcar '(lambda (x) (strcat "\n----\n" x)) (wiki-strtolst "1 John,\"2 2\"\" pipe,\nheated\",3 the end,,,,," "," "\"" T)))) |
+ | ;;;(alert (apply 'strcat (mapcar '(lambda (x) (strcat "\n----\n" x)) (wiki-strtolst "1 John,\"2 2\"\" pipe,\nheated\",3 the end,,,,," "`," "\"" T)))) |
(DEFUN |
(DEFUN |
||
WIKI-STRTOLST (INPUTSTRING FIELDSEPARATORWC TEXTDELIMITER |
WIKI-STRTOLST (INPUTSTRING FIELDSEPARATORWC TEXTDELIMITER |
||
EMPTYFIELDSDOCOUNT / CHARACTERCOUNTER CONVERSIONISDONE |
EMPTYFIELDSDOCOUNT / CHARACTERCOUNTER CONVERSIONISDONE |
||
CURRENTCHARACTER CURRENTFIELD CURRENTFIELDISDONE |
CURRENTCHARACTER CURRENTFIELD CURRENTFIELDISDONE |
||
− | PREVIOUSCHARACTER RETURNLIST |
+ | FIRSTCHARACTERINDEX PREVIOUSCHARACTER RETURNLIST |
+ | TEXTMODEISON |
||
) |
) |
||
;;Initialize the variables for clarity's sake |
;;Initialize the variables for clarity's sake |
||
(SETQ |
(SETQ |
||
+ | ;;For the AutoLISP (substr string index length) function, the first character index is 1 |
||
⚫ | |||
+ | FIRSTCHARACTERINDEX 1 |
||
+ | ;;We start the character counter one before the beginning |
||
⚫ | |||
+ | (1- FIRSTCHARACTERINDEX) |
||
PREVIOUSCHARACTER "" |
PREVIOUSCHARACTER "" |
||
CURRENTCHARACTER "" |
CURRENTCHARACTER "" |
||
Line 43: | Line 55: | ||
;;Make sure that the FieldSeparatorWC is not empty. |
;;Make sure that the FieldSeparatorWC is not empty. |
||
(COND |
(COND |
||
− | ;;If |
+ | ;;If the FieldSeparatorWC is an empty string, |
− | (( |
+ | ((= FIELDSEPARATORWC "") |
;;Then |
;;Then |
||
;;1. Give an alert about the problem. |
;;1. Give an alert about the problem. |
||
Line 68: | Line 80: | ||
PREVIOUSCHARACTER |
PREVIOUSCHARACTER |
||
CURRENTCHARACTER |
CURRENTCHARACTER |
||
− | ;;CharacterCounter |
+ | ;;CharacterCounter is initialized above to start 1 before first character. Increment it. |
CHARACTERCOUNTER |
CHARACTERCOUNTER |
||
(1+ CHARACTERCOUNTER) |
(1+ CHARACTERCOUNTER) |
||
Line 77: | Line 89: | ||
;;Decide what to do with CurrentCharacter. |
;;Decide what to do with CurrentCharacter. |
||
(COND |
(COND |
||
+ | ;;If |
||
⚫ | |||
+ | ((AND |
||
⚫ | |||
+ | ;;there is a TextDelimiter, |
||
+ | (/= TEXTDELIMITER "") |
||
⚫ | |||
⚫ | |||
+ | ) |
||
+ | ;;then |
||
;;1. Toggle the TextModeIsOn flag |
;;1. Toggle the TextModeIsOn flag |
||
(IF (NOT TEXTMODEISON) |
(IF (NOT TEXTMODEISON) |
||
Line 129: | Line 147: | ||
(NOT (WCMATCH PREVIOUSCHARACTER FIELDSEPARATORWC)) |
(NOT (WCMATCH PREVIOUSCHARACTER FIELDSEPARATORWC)) |
||
;;the ReturnList is still nil due to only empty non-counting fields in string, |
;;the ReturnList is still nil due to only empty non-counting fields in string, |
||
− | ;;( |
+ | ;;(Added 2008-02-18 TGH. Bug fix.) |
(= RETURNLIST NIL) |
(= RETURNLIST NIL) |
||
) |
) |
||
Line 159: | Line 177: | ||
;;Reverse the backwards return list and we are done. |
;;Reverse the backwards return list and we are done. |
||
(REVERSE RETURNLIST) |
(REVERSE RETURNLIST) |
||
+ | )</pre> |
||
− | ) |
||
− | ;|«Visual LISP© Format Options» |
||
− | (72 2 40 2 nil "end of " 60 2 2 2 1 nil nil nil T) |
||
− | ;*** DO NOT add text below the comment! ***|; |
||
⚫ | |||
{{AutoLISPfooter}} |
{{AutoLISPfooter}} |
||
<noinclude>[[Category:AutoLISP function]]</noinclude> |
<noinclude>[[Category:AutoLISP function]]</noinclude> |
Latest revision as of 22:42, 1 February 2009
;;;WIKI-STRTOLST ;;;Parses a string into a list of fields. ;;;Usage: (wiki-strtolst ;;; [InputString containing fields] ;;; [FieldSeparatorWC field delimiter wildcard string ;;; Use "`," for comma and " ,\t" for white space ;;; ] ;;; [TextDelimiter text delimiter character.] ;;; [EmptyFieldsDoCount flag. ;;; If nil, consecutive field delimiters are ignored. ;;; Nil is good for word (white space) delimited strings. ;;; ] ;;; ) ;;; Examples: ;;; CSV (wiki-strtolst string "`," "\"" T) ;;; Word delimited (wiki-strtolst string " ,\t,\n" "" nil) ;;; Revision history ;;; 2009-01-17 TGH Replaced test for empty fieldseparatorwc with a simple '= function ;| Edit the source code for this function at
http://autocad.wikia.com/wiki/Strtolst_(AutoLISP_function)
|; ;;;Avoid cleverness. ;;;Human readability trumps elegance and economy and cleverness here. ;;;This should be readable to a programmer familiar with any language. ;;;In this function, I'm trying to honor readability in a new (2008) way. ;;;And I am trying a new commenting style. ;;;Tests ;;;(alert (apply 'strcat (mapcar '(lambda (x) (strcat "\n----\n" x)) (wiki-strtolst "1 John,\"2 2\"\" pipe,\nheated\",3 the end,,,,," "`," "\"" nil)))) ;;;(alert (apply 'strcat (mapcar '(lambda (x) (strcat "\n----\n" x)) (wiki-strtolst "1 John,\"2 2\"\" pipe,\nheated\",3 the end,,,,," "`," "\"" T)))) (DEFUN WIKI-STRTOLST (INPUTSTRING FIELDSEPARATORWC TEXTDELIMITER EMPTYFIELDSDOCOUNT / CHARACTERCOUNTER CONVERSIONISDONE CURRENTCHARACTER CURRENTFIELD CURRENTFIELDISDONE FIRSTCHARACTERINDEX PREVIOUSCHARACTER RETURNLIST TEXTMODEISON ) ;;Initialize the variables for clarity's sake (SETQ ;;For the AutoLISP (substr string index length) function, the first character index is 1 FIRSTCHARACTERINDEX 1 ;;We start the character counter one before the beginning CHARACTERCOUNTER (1- FIRSTCHARACTERINDEX) PREVIOUSCHARACTER "" CURRENTCHARACTER "" CURRENTFIELD "" CURRENTFIELDISDONE NIL TEXTMODEISON NIL CONVERSIONISDONE NIL RETURNLIST NIL ) ;;Make sure that the FieldSeparatorWC is not empty. (COND ;;If the FieldSeparatorWC is an empty string, ((= FIELDSEPARATORWC "") ;;Then ;;1. Give an alert about the problem. (ALERT ;;Include princ to allow user to see and copy error ;;after dismissing alert box. (PRINC (STRCAT "\n\"" FIELDSEPARATORWC "\" is not a valid field delimiter." ) ) ) ;;2. Exit with error. (EXIT) ) ) ;;Start the main character-by-character InputString examination loop. (WHILE (NOT CONVERSIONISDONE) (SETQ ;;Save CurrentCharacter as PreviousCharacter. PREVIOUSCHARACTER CURRENTCHARACTER ;;CharacterCounter is initialized above to start 1 before first character. Increment it. CHARACTERCOUNTER (1+ CHARACTERCOUNTER) ;;Get new CurrentCharacter from InputString. CURRENTCHARACTER (SUBSTR INPUTSTRING CHARACTERCOUNTER 1) ) ;;Decide what to do with CurrentCharacter. (COND ;;If ((AND ;;there is a TextDelimiter, (/= TEXTDELIMITER "") ;;and CurrentCharacter is a TextDelimiter, (= CURRENTCHARACTER TEXTDELIMITER) ) ;;then ;;1. Toggle the TextModeIsOn flag (IF (NOT TEXTMODEISON) (SETQ TEXTMODEISON T) (SETQ TEXTMODEISON NIL) ) ;;2. If this is the second consecutive TextDelimiter character, then (IF (= PREVIOUSCHARACTER TEXTDELIMITER) ;;Output it to CurrentField. (SETQ CURRENTFIELD (STRCAT CURRENTFIELD CURRENTCHARACTER)) ) ) ;;Else if CurrentCharacter is a FieldDelimiter wildcard match, ((WCMATCH CURRENTCHARACTER FIELDSEPARATORWC) ;;Then (COND ;;If TextModeIsOn = True, then ((= TEXTMODEISON T) ;;Output CurrentCharacter to CurrentField. (SETQ CURRENTFIELD (STRCAT CURRENTFIELD CURRENTCHARACTER)) ) ;;Else if ((OR ;;EmptyFieldsDoCount, or (= EMPTYFIELDSDOCOUNT T) ;;the CurrentField isn't empty, (/= "" CURRENTFIELD) ) ;;Then ;;Set the CurrentFieldIsDone flag to true. (SETQ CURRENTFIELDISDONE T) ) (T ;;Else do nothing ;;Do not flag the CurrentFieldDone, ;;nor output the CurrentCharacter. NIL ) ) ) ;;Else if CurrentCharacter is empty, ((= CURRENTCHARACTER "") ;;Then ;;We are at the end of the string. ;;1. Flag ConversionIsDone. (SETQ CONVERSIONISDONE T) ;;2. If (IF (OR ;;EmptyFieldsDoCount, or EMPTYFIELDSDOCOUNT ;;the PreviousCharacter wasn't a FieldSeparatorWC, or (NOT (WCMATCH PREVIOUSCHARACTER FIELDSEPARATORWC)) ;;the ReturnList is still nil due to only empty non-counting fields in string, ;;(Added 2008-02-18 TGH. Bug fix.) (= RETURNLIST NIL) ) ;;Then flag the CurrentFieldIsDone to wrap up the last field. (SETQ CURRENTFIELDISDONE T) ) ) ;;Else (CurrentCharacter is something else), (T ;;Output CurrentCharacter to CurrentField. (SETQ CURRENTFIELD (STRCAT CURRENTFIELD CURRENTCHARACTER)) ) ) ;;If CurrentFieldIsDone, (IF CURRENTFIELDISDONE ;;Then ;;Output it to the front of ReturnList. (SETQ RETURNLIST (CONS CURRENTFIELD RETURNLIST) ;;Start a new CurrentField. CURRENTFIELD "" CURRENTFIELDISDONE NIL ) ) ;;End the main character-by-character InputString examination loop. ) ;;Reverse the backwards return list and we are done. (REVERSE RETURNLIST) )