template := directive [ assignment ] [ template ]
|
{ | variable name | } |
. |
The assignment portion of a directiive assignment pair is optional, meaning that a valid template can include consecutive directives.
PARSE VALUE "This is a sentence." WITH firstword secondword restofstringis equivalent to
PARSE VAR restofstring thirdword fourthword restofstringis equivalent to
If there are more words in string than variables in the template, the last variable is assigned the "rest" of the string. If there are more symbols in the template than words in the string the excess symbols are assigned the null string value.
NOTE: A construction such as PARSE VALUE ƒ1() ƒ2() … WITH word1 word2 … will not return the expected results if any of the ƒ() returns a result that includes a character that blank-delimits a "word." For example, if ƒ2() evaluates to a result that includes an embedded ASCII space, it evaluates to two words, so word3 gets the second and word4 is assigned the first word resulting from ƒ3().PARSE VALUE ƒ1() c2x(ƒ2()) … WITH word1 word2 …
word2 = x2c(word2)
gives the desired result if ƒ2() might return a binary value that coincidentally is a word-delimiter.
Be especially aware that "blank-delimited" words may be defined by delimiters other than <SPACE>. In particular it is common for interpreters to include the <TAB> charachter. So word1<TAB><TAB> word3 would result in only two "words" being returned. To parse an ASCII line from a tab-delimited text file that might have "empty" column values, use
tab = '09'x … PARSE VALUE line WITH field1 (tab) field2 (tab) …so that the match pattern directive is used instead of the space directive.
01-Sep-12 Colorado St Colorado Denver CO ....'....1....'....2....'....3....'....4....'....5....'....6....'....7....'....8....'....9(The "ruler" line is not a part of the record, of course.)
PARSE VAR record 1 filedate 10 . 11 visitor 40 home 69 location
is the same as
date = "01-Sep-12"; visitor = "Colorado St "; home = "Colorado "; location = "Denver CO "start may be any positive value. In particular it can be left of the current position.
PARSE VAR record 1 filedate +9 . +2 visitor +29 home +29 locationmakes the same assignments as the template that explicitly specifies the columns that define the assignments.
Note that start is incremented (or decremented) from its value prior to the assignment that precedes the directive. That is to say it is the start set by the immediately prior directive ±m characters (including spaces.)
PARSE VAR record dd '-' mmm '-' yy . '09'x visitor '09'x home '09'x location '09'x .defines the same variables as above except that instead of filedate the date is divided into it's constituent parts based upon the "matching" dashes. Note that the "." following yy makes the space preceding the "." the space directive, so yy does not include the trailing blank between "-12" and the next tab character.
nextvalue = expression nexti = stem.0+1 stem.nexti = nextvalue stem.0 = nextican be replaced with:
PARSE VALUE stem.0+1 expression WITH nexti stem.nexti =1 stem.0 .
Directive types 2, 3 and 4 can themselves be specified as variables. For instance, if we have tab = X2C(09) the type 4 example could have been written as:
PARSE VAR record dd '-' mmm '-' yy . (tab) visitor (tab) home (tab) location (tab) .
PARSE VALUE string WITH =(start) substring +(length)
is identical to
substring = SUBSTR(string,start,length)
PARSE is also measurably faster except for trivially short strings.
The variable name enclosed in parentheses may be defined in the template itself. For instance, if qstring is /delimited string/ then
PARSE VAR qstring =1 delim =2 qstring2 (delim)sets qstring2 to qstring with the leading and trailing "/" characters removed.
Suppose record contains
"01-Sep-12",Colorado St,Colorado,"Denver, CO"The following loop separates this "comma separated values" line into its component fields (saved as a stem variable) and removes any quotations used to preserve embedded commas.
and when applied to record results in
q = "'"; qq = '"' field. = ''; fix = 0 DO WHILE record \= '' PARSE VAR record =1 tst +1 . /* tst=1st char of (next) field */ IF POS(tst,q qq) \= 0 THEN DO tstend = tst',' PARSE VAR record =2 nxtfield (tstend) record /* nxtfield is what is between " and ", */ END ELSE PARSE VAR record nxtfield ',' record /* nxtfield is what is between , and , */ PARSE VALUE fix+1 nxtfield WITH fix field.fix END field.0 = fix
field.0 = 4 field.1 = "01-Sep-12" field.2 = "Colorado St" field.3 = "Colorado" field.4 = "Denver, CO"
At the end of the loop words is the null string, but word.i is what WORD(words, i) would have returned.
n = WORDS(words) DO ix = 1 FOR n PARSE VAR words word.ix words END word.0 = n
See WORD() vs PARSE for a relative performance analysis and generalization of this example to use arbitrary delimiters.
For more examples see Parallel Assignments.