No edit summary |
No edit summary |
||
Line 28: | Line 28: | ||
;;;(alert (apply 'strcat (mapcar '(lambda (x) (strcat "\n----\n" x)) (haws-strtolst "1 John,\"2 2\"\" pipe,\nheated\",3 the end,,,,," "," "\"" nil)))) |
;;;(alert (apply 'strcat (mapcar '(lambda (x) (strcat "\n----\n" x)) (haws-strtolst "1 John,\"2 2\"\" pipe,\nheated\",3 the end,,,,," "," "\"" nil)))) |
||
;;;(alert (apply 'strcat (mapcar '(lambda (x) (strcat "\n----\n" x)) (haws-strtolst "1 John,\"2 2\"\" pipe,\nheated\",3 the end,,,,," "," "\"" T)))) |
;;;(alert (apply 'strcat (mapcar '(lambda (x) (strcat "\n----\n" x)) (haws-strtolst "1 John,\"2 2\"\" pipe,\nheated\",3 the end,,,,," "," "\"" T)))) |
||
− | + | (DEFUN |
|
STRTOLST (INPUTSTRING FIELDSEPARATORWC TEXTDELIMITER |
STRTOLST (INPUTSTRING FIELDSEPARATORWC TEXTDELIMITER |
||
EMPTYFIELDSDOCOUNT / CHARACTERCOUNTER CONVERSIONISDONE |
EMPTYFIELDSDOCOUNT / CHARACTERCOUNTER CONVERSIONISDONE |
||
Line 156: | Line 156: | ||
;;Reverse the backwards return list and we are done. |
;;Reverse the backwards return list and we are done. |
||
(REVERSE RETURNLIST) |
(REVERSE RETURNLIST) |
||
− | + | ) |
|
</pre> |
</pre> |
||
{{AutoLISPfooter}} |
{{AutoLISPfooter}} |
Revision as of 04:52, 28 February 2008
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
;;; AutoCAD Wiki AutoLISP code header. ;;; ;;; Copy this code to a file on your computer. ;;; Start highlighting OUTSIDE the code boxes and use the mouse or keyboard to ;;; highlight all the code. ;;; If you select too much, simply delete any extra from your destination file. ;;; In Windows you may want to start below the code and use [Shift]+[Ctrl]+[Home] ;;; key combination to highlight all the way to the top of the article, ;;; then still holding the [Shift] key, use the arrow keys to shrink the top of ;;; the selection down to the beginning of the code. Then copy and paste. ;;; This program is free software: you can redistribute it and/or modify ;;; it under the terms of the GNU General Public License as published by ;;; the Free Software Foundation, either version 3 of the License, or ;;; (at your option) any later version. ;;; ;;; This program is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; The working version of this software is located at the AutoCAD Wiki. ;;; Please AutoCAD:Be_bold in adding clarifying comments and improvements at ;;; https://autocad.fandom.com/wiki/Strtolst_(AutoLISP_function)
;;;STRTOLST ;;;Parses a string into a list of fields. ;;;Usage: (strtolst ;;; [InputString containing fields] ;;; [FieldSeparatorWC field delimiter wildcard string] ;;; [TextDelimiter text delimiter character. ;;; Use "`," for comma and " ,\t,\n" for white space] ;;; [EmptyFieldsDoCount flag. ;;; If nil, consecutive field delimiters are ignored. ;;; Nil is good for word (white space) delimited strings. ;;; ] ;;; ) ;;;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. ;;; ;;; Versions ;;; 2008-01-12 TGH Coded from scratch ;;; ;;;Tests ;;;(alert (apply 'strcat (mapcar '(lambda (x) (strcat "\n----\n" x)) (haws-strtolst "1 John,\"2 2\"\" pipe,\nheated\",3 the end,,,,," "," "\"" nil)))) ;;;(alert (apply 'strcat (mapcar '(lambda (x) (strcat "\n----\n" x)) (haws-strtolst "1 John,\"2 2\"\" pipe,\nheated\",3 the end,,,,," "," "\"" T)))) (DEFUN STRTOLST (INPUTSTRING FIELDSEPARATORWC TEXTDELIMITER EMPTYFIELDSDOCOUNT / CHARACTERCOUNTER CONVERSIONISDONE CURRENTCHARACTER CURRENTFIELD CURRENTFIELDISDONE PREVIOUSCHARACTER RETURNLIST TEXTMODEISON ) ;;Initialize the variables for clarity's sake (SETQ CHARACTERCOUNTER 0 PREVIOUSCHARACTER "" CURRENTCHARACTER "" CURRENTFIELD "" CURRENTFIELDISDONE NIL TEXTMODEISON NIL CONVERSIONISDONE NIL RETURNLIST NIL ) ;;Make sure that the FieldSeparatorWC is not empty. (COND ;;If an empty string matches the FieldSeparatorWC, then ((WCMATCH "" FIELDSEPARATORWC) ;;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 starts at 0 above. Increment it. CHARACTERCOUNTER (1+ CHARACTERCOUNTER) ;;Get new CurrentCharacter from InputString. CURRENTCHARACTER (SUBSTR INPUTSTRING CHARACTERCOUNTER 1) ) ;;Decide what to do with CurrentCharacter. (COND ;;If CurrentCharacter is a TextDelimiter, then ((= CURRENTCHARACTER TEXTDELIMITER) ;;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, then ((WCMATCH CURRENTCHARACTER FIELDSEPARATORWC) (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, then ((= CURRENTCHARACTER "") ;;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, then (NOT (WCMATCH PREVIOUSCHARACTER FIELDSEPARATORWC)) ) ;;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, then (IF CURRENTFIELDISDONE ;;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) )