REXX Tips & Tricks, Version 2.80


Inf-HTML [About][Toc][Index] 0.9b (c) 1995 Peter Childs


The PARSE instruction



This section contains a more detailed description of the <PARSE 
instruction. 
---------- * ----------

General 
The format of the <PARSE instruction is 
   PARSE {UPPER|LOWER|CASELESS} source {template}

where 
 UPPER 
    Translate the source to uppercase before parsing. This parameter is 
    optional . 
 LOWER 
    Translate the source to lowercase before parsing. This parameter is 
    optional (Object REXX only!). 
 CASELESS 
    Parse the source ignoring the case (e.g. A-Z is equal to a-z). This 
    parameter is optional (Object REXX only!).   
 source 
    The source to parse (see below) 
 template 
    This parameter specifies how to parse the source (see below). This 
    parameter is optional. 
 
 ----- * -----
 
 source may be one of the following: 
 ARG 
    Use the arguments for the program or procedure as source 
 LINEIN 
    Use the next input line from the keyboard as source. PARSE LINEIN is a 
    short form of PARSE VALUE LINEIN() WITH 
 PULL 
    Use the next line from the default REXX queue or the next line from 
    the keyboard if the queue is empty as source 
 SOURCE 
    Use the program's source information as source (see PARSE SOURCE) 
 VALUE expression WITH 
    Use the result of the expression expression as source. expression may 
    be any legal REXX expression. 
 VAR name 
    Use the contents of the variable name as source 
 VERSION 
    Use the REXX interpreter version information as source (see PARSE 
    VERSION) 
 
 ----- * -----
 
 template can be any combination of the following patterns: 
 variable name 
    a variable to be assigned a value 
 literal string 
    a literal string used as string pattern to split the source 
 (variable name) 
    a literal string saved in a variable used as a string pattern to split 
    the source 
 . (a single period) 
    a placeholder for unused parts of the source. You must use at least 
    one space to separate periods from other patterns. 
 # (# is an integer value, e.g. 4 ) 
    an absolute character position within the source 
 =# (# is an integer value, e.g. =4 ) 
    an absolute character position within the source 
 +# (# is an integer value, e.g. +4 ) 
    a relative character position within the source (move right) 
 -# (# is an integer value, e.g. -4 ) 
    a relative character position within the source (move left) 
 =(variable name) 
    a variable containing an absolute character position within the source 
    
 +(variable name) 
    a variable containing a relative character position within the source 
    (move right) 
 -(variable name) 
    a variable containing a relative character position within the source 
    (move left) 
 
 ---------- * ----------
 
 General notes 
 Templates are processed from left to right. The <PARSE instruction does 
 not change the source string (i.e., if you don't force it to do this; see 
 below). 
 ---------- * ----------
 
 Hints for selecting the proper template 
 Use only variables if you want to split the string into words. 
 Example: 

  
 /* parse into words                                                   */
 
   testString = "This    is       a       Test "
 
   parse var TestString var1 var2 var3 var4
 
         /* result:                                                    */
         /* -> var1 = "This", var2 = "is", var3 = "a" and              */
         /*    var4 = "       Test "                                   */
 
 
 
 In this example <PARSE splits the source string into words (separated 
 with one or more blanks) and copies these words into the variables used 
 in the template. The blanks between the words are not saved in a variable 
 -- with one exception: The blanks around the word(s) for the last 
 variable are saved in the last variable. To avoid this, you may add a 
 period at the end of the template. 
 Example: 

  
   /* parse into words                                                 */
   /* use a period at the end of the template to suppress the spaces   */
   /* surrounding the string in the last variable                      */
 
   testString = "This    is       a       Test "
 
   parse var TestString var1 var2 var3 var4 .
 
         /* result:                                                    */
         /* -> var1 = "This", var2 = "is", var3 = "a" and              */
         /*    var4 = "Test"                                           */
 
 
 
  Note that if there's only one variable in the template, that variable is 
 also the last variable! 
 Further note that <PARSE only uses spaces as the word delimiter. If, for 
 example, the source string uses tabulators ("09"x) to separate the words, 
 you can either use parsing with string patterns (see below) or you can 
 use the function <translate before parsing the string. 
 Example: 

  
   /* translate tabulator to spaces and parse into words               */
 
   testString = "This    is" || "09"x || "another    Test"
 
                     /* translate tabulators to spaces                 */
   TestString = translate( testString, " ", "09"x )
   parse var TestString var1 var2 var3 var4 .
 
         /* result:                                                    */
         /* -> var1 = "This", var2 = "is", var3 = "another" and        */
         /*    var4 = "Test"                                           */
 
 
 ----- * -----
 
 Use string patterns if you want to split the string after one or more 
 special substrings. 
 Example: 

  
 /* parse with string patterns                                         */
 
   testString = "datafields=data1//data2//data3"
 
   parse var testString keyName "=" value1 "//" value2 "//" value3
 
         /* result:                                                    */
         /* -> keyName = "datafields", value1 = "data1",               */
         /*    value2 = "data2" and value3 = "data3"                   */
 
 
 In this example <PARSE splits the string into substrings before and after 
 the string patterns. The string patterns are not saved in a variable. 
 ----- * -----
 
 Use positional parsing if the source is built out of fields with fixed 
 length. 
 Example: 

  
 /* absolute positional parsing                                        */
 
 /*              0        1         2         3         4         5    */
 /*    position: 12345678901234567890123456789012345678901234567890123 */
   testString = "Doe       John M.   03/03/65  New York            USA";
 
   parse var testString name1 11 name2 21 birthday 31 town 51 country
 
         /* result:                                                    */
         /*                0        1         2         3              */
         /*                123456789012345678901234567890              */
         /* -> name1    = "Doe       "                                 */
         /*    name2    = "John M.   "                                 */
         /*    birthday = "03/03/65  "                                 */
         /*    town     = "New York            "                       */
         /*    country  = "USA"                                        */
 
 
 In this example <PARSE splits the source string at the given positions 
 into substrings and copies these substrings into the variables. All 
 characters from the source string (including the spaces) are saved in a 
 variable. 
 You can also use relative positional parsing in this case. 
 Example: 

  
 /* relative positional parsing                                        */
 
 /*              0        1         2         3         4         5    */
 /*    position: 12345678901234567890123456789012345678901234567890123 */
   testString = "Doe       John M.   03/03/65  New York            USA";
 
   parse var testString name1 +10 name2 +10 birthday +10 town +20 country
 
         /* result:                                                    */
         /*                0        1         2         3              */
         /*                123456789012345678901234567890              */
         /* -> name1    = "Doe       "                                 */
         /*    name2    = "John M.   "                                 */
         /*    birthday = "03/03/65  "                                 */
         /*    town     = "New York            "                       */
         /*    country  = "USA"                                        */
 
 
 Positional patterns that specify a position beyond the end of the parse 
 data are considered to match the end of the data.  Positional patterns 
 that specify a position to the left of the beginning of the parse data 
 are considered to match the beginning of the parse data. 
 ----- * -----
 
 You can also mix string patterns, positional parsing and variables in one 
 <PARSE instruction. 
 Example: 

  
 /* mixed parsing                                                      */
 
 /*              0        1         2         3         4         5    */
 /*    position: 1234567890123456789012345678901234567890123456789012  */
   testString = "This a remark field (up to 39 chars)   44 55 //66    77";
 
   parse var testString 40 data1 data2 . "//" data3 data4 .
 
         /* result:                                                    */
         /* -> data1 = "44", data2 = "55", data3 = "66" and            */
         /*    data4 = "77"                                            */
 
 
 ----- * -----
 
 Further considerations 
 Use the placeholder . (period) to ignore parts of the source. 
 Example: 

  
 /* parsing into word using periods in templates                       */
 
   testString = "data1 garbage data2 garbage garbage data3 garbage";
 
   parse var testString resultStr1 . resultStr2 . . resultStr3 .
 
         /* result:                                                    */
         /* -> resultStr1 = "data1", resultStr2 = "data2" and          */
         /*    resultStr3 = "data3"                                    */
 
 
 Note that the placeholder is not necessary in all cases. 
 Example: 

  
 /* examples for using the placeholder                                 */
 
   testString = "data1-data2-data3"
   parse var testString . '-' resultStr '-' .
         /* -> resultStr = "data2"                                     */
 
   /* is equal to */
   parse var testString '-' resultStr '-'
         /* -> resultStr = "data2"                                     */
 
   parse var testString . 7 resultStr +5 .
         /* -> resultStr = "data2"                                     */
 
   /* is equal to */
   parse var testString 7 resultStr +5
         /* -> resultStr = "data2"                                     */
 
 
 
 ----- * -----
 
 All variables in a template receive new values. If there are no more 
 words for one or more variables in the source, the remaining variables 
 receive an empty string. 
 Example: 

  
 /* further parsing example                                            */
 
   parse value "word1 word2" WITH resultStr1 resultStr2 resultStr3
 
         /* result:                                                    */
         /* -> resultStr1 = "word1", resultStr2 = "word2" and          */
         /*    resultStr3 = ""                                         */
 
 
 In this example the variable resultStr3 contains an empty string after 
 the <PARSE instruction because there are two words in the source but the 
 template contains three variables. 
 Another example 

  
 /* further parsing example                                            */
 
   parse value "s1 // s2 s3" WITH resStr1 "//" resStr2 "--" resStr3
 
         /* result:                                                    */
         /* -> resStr1 = "s1 ", resStr2 = " s2 s3", resStr3 = ""       */
 
 
 In this example the variable resStr3 contains an empty string after the 
 <PARSE instruction because there is no match for the string pattern "--" 
 in the source string. 
 ----- * -----
 
 If there are more words in the source than variables in the template, the 
 last variable receives all words remaining in the source. 
 Example: 

  
 /* further parsing example                                            */
 
   parse value "word1 word2 word3" WITH resultStr1 resultStr2
 
         /* result:                                                    */
         /* -> resultStr1 = "word1", resultStr2 = "word2 word3"        */
 
 
 In this example the variable resultStr2 contains "word2 word3" because 
 there are three words in the source but only two variables in the 
 template. 
 ----- * -----
 
 An empty string (e.g. "") in the template is never found. It always 
 matches the end of the string (see Get the first and the last char of a 
 string for an example). 
 Example: 

  
 /* parse a string from the end                                        */
 
   testString = "anything not needed      44 55 66 77"
 
   parse var testString "" -2 var1 +2 -5 var2 +2 -5 var3 +2 -5 var4 +2
 
         /* result:                                                    */
         /* -> var1 = "77", var2 = "66", var3 = "55" and var4 = "44"   */
 
 
 ----- * -----
 
 In <PARSE VAR instructions you can use the source in the template. You 
 can use this method to process a variable word by word. 
 Example: 

  
 /* process a string word by word                                      */
 
   testString = "Otto Karl Heinrich Klaus Peter"
 
   do until testString = ""
 
                     /* copy the 1. word of testString into curName    */
                     /* remove it from testString                      */
     parse var testString curName testString
 
     say "Current word is " || curName
     say "Remaining words in testString are " || testString
   end /* do until testString = "" */
 
 
 ----- * -----
 
 You can set a variable in a template and use it in the remaining 
 template. 
 Example: 

  
 /* further parsing example                                            */
 
   testString = "*data1*data2*data3*"
 
   parse var TestString sep 2 resStr1 (sep) resStr2 (sep) resStr3 (sep)
         /*             \ /             |             |             |  */
         /*              |              \-------------+-------------/  */
         /*             set the            use the variable "sep"      */
         /*             variable "sep"                                 */
         /*                                                            */
         /* result:                                                    */
         /* -> resStr1 = "data1", resStr2 = "data2", resStr3 = "data3" */
         /*    sep = "*"                                               */
 
 
 ----- * -----
 
 Only <PARSE ARG can have more than one source string (separate the source 
 strings with commas). 
 Example: 

  
 /* further parsing example                                            */
 
   call TestFunc "data11,data12" , "data21data22"
 
 RETURN
 
 TestFunc:
     /* Note the difference meaning of the commas in the template!     */
 
   parse arg arg1_part1 ',' arg1_part2 , arg2_part1 7 arg2_part2
 
         /* result:                                                    */
         /* -> arg1_part1 = "data11", arg1_part2 = "data12"            */
         /*    arg2_part1 = "data21", arg2_part2 = "data22"            */
 RETURN
 
 
 Note that a REXX program called from the command line always retrieves 
 only one parameter (see also Parameters for a REXX program). 
 ----- * -----
 
 Using positional parsing you can parse the source string with different 
 templates in one <PARSE instruction. 
 Example: 

  
 /* sample for parsing a string with different templates in one PARSE  */
 /* instruction                                                        */
 
   testString = "a--b c++d r//g"
 
   parse value testString with   word1 word2 word3 ,
                           1 part1 "--" part2 "++" part3 "//" part4 ,
                           1 char1 2 4 char2 5 9 char3 10 char4 11 14 char5
 
         /* result:                                                    */
         /* -> word1 = "a--b", word2 = "c++d", word3 = "r//g"          */
         /*    part1 = "a", part2 = "b c", part3 = "d r"               */
         /*    char1 = "a", char2 = "b", char3 = "d", char4 = "r",     */
         /*    char5 = "g"                                             */
 
 
 ---------- * ----------
 
 See the next chapter for some further examples.   

Inf-HTML End Run - Successful