Product Site

9.3. Templates Containing Positional (Numeric) Patterns

A positional pattern is a number that identifies the character position at which the data in the source string is to be split. The number must be a whole number.

An absolute positional pattern is:

The number specifies the absolute character position at which the source string is to be split.

Here is a template with absolute positional patterns:
variable1 11 variable2 21 variable3

The numbers 11 and 21 are absolute positional patterns. The number 11 refers to the 11th position in the input string, 21 to the 21st position. This template puts characters:

Positional patterns are probably most useful for working with a file of records, such as:

The following example uses this record structure:
Example 9.9. Parsing stems
/* Parsing with absolute positional patterns in template         */
record.1="Clemens   Samuel    Mark Twain          "
record.2="Evans     Mary Ann  George Eliot        "
record.3="Munro     H.H.      Saki                "
do n=1 to 3
  parse var record.n lastname 11 firstname 21 pseudonym
  If lastname="Evans" & firstname="Mary Ann" then say "By George!"
end                         /* Says "By George!" after record 2  */

The source string is split at character position 11 and at position 21. The language processor assigns characters 1 to 10 to lastname, characters 11 to 20 to firstname, and characters 21 to 40 to pseudonym.

The template could have been:
1 lastname 11 firstname 21 pseudonym

instead of
lastname 11 firstname 21 pseudonym

Specifying 1 is optional.

Optionally, you can put an equal sign before a number in a template. An equal sign is the same as no sign before a number in a template. The number refers to a particular character position in the source string. These two templates are equal:
lastname  11 first  21 pseudonym
lastname =11 first =21 pseudonym

A relative positional pattern is a number with a plus (+) or minus (-) sign preceding it. It can also be an expression within parentheses, with a plus (+) or minus (-) sign preceding the left parenthesis; for details see Section 9.4, “Parsing with Variable Patterns”.

The number specifies the relative character position at which the source string is to be split. The plus or minus indicates movement right or left, respectively, from the start of the string (for the first pattern) or from the position of the last match. The position of the last match is the first character of the last match. Here is the same example as for absolute positional patterns done with relative positional patterns:
Example 9.10. Parsing with relative positional patterns
/* Parsing with relative positional patterns in template         */
record.1="Clemens   Samuel    Mark Twain          "
record.2="Evans     Mary Ann  George Eliot        "
record.3="Munro     H.H.      Saki                "
do n=1 to 3
  parse var record.n lastname +10 firstname + 10 pseudonym
  If lastname="Evans" & firstname="Mary Ann" then say "By George!"
end                                             /* same results  */

Whitespace characters between the sign and the number are insignificant. Therefore, +10 and + 10 have the same meaning. Note that +0 is a valid relative positional pattern.

Absolute and relative positional patterns are interchangeable except in the special case (see Section 9.8.2, “Combining String and Positional Patterns”) when a string pattern precedes a variable name and a positional pattern follows the variable name. The templates from the examples of absolute and relative positional patterns give the same results.

With positional patterns, a matching operation can back up to an earlier position in the source string. Here is an example using absolute positional patterns:
/* Backing up to an earlier position (with absolute positional)  */
string="astronomers"
parse var string 2 var1 4 1 var2 2 4 var3 5 11 var4
say string "study" var1||var2||var3||var4
/* Displays: "astronomers study stars"                           */

The absolute positional pattern 1 backs up to the first character in the source string.

With relative positional patterns, a number preceded by a minus sign backs up to an earlier position. Here is the same example using relative positional patterns:
/* Backing up to an earlier position (with relative positional)  */
string="astronomers"
parse var string 2 var1 +2 -3 var2 +1 +2 var3 +1 +6 var4
say string "study" var1||var2||var3||var4      /* same results   */

In the previous example, the relative positional pattern -3 backs up to the first character in the source string.

The templates in the previous two examples are equivalent.

You can use templates with positional patterns to make several assignments:
/* Making several assignments                                    */
books="Silas Marner, Felix Holt, Daniel Deronda, Middlemarch"
parse var books 1 Eliot 1 Evans
/* Assigns the (entire) value of books to Eliot and to Evans.    */

A length positional pattern is a number with a > or < preceding it. It can also be an expression within parentheses, with a > or < preceding the left parenthesis; for details see Section 9.4, “Parsing with Variable Patterns”.

The number specifies the length at which the source string is to be split, relative to the current position. The > or < indicates movement right or left, respectively, from the start of the string (for the first pattern) or from the position of the last match. The position of the last match is the first character of the last match. Here is the same example as for relative positional patterns done with length positional patterns:
Example 9.11. Parsing with relative positional patterns
/* Parsing with relative positional patterns in template         */
record.1="Clemens   Samuel    Mark Twain          "
record.2="Evans     Mary Ann  George Eliot        "
record.3="Munro     H.H.      Saki                "
do n=1 to 3
  parse var record.n lastname >10 firstname >10 pseudonym
  If lastname="Evans" & firstname="Mary Ann" then say "By George!"
end                                             /* same results  */

Whitespace characters between the trigger and the number are insignificant. Therefore, >10 and > 10 have the same meaning. Note that >0 and <0 are valid length positional patterns.

The > length pattern and the + relative positional pattern are interchangeable except in the special case of the value 0. A >0 pattern will split the string into a null string and leave the match position unchanged. This is particularly useful for parsing off length-qualified fields from a string.
Example 9.12. Parsing with length patterns
/* Parsing with length patterns in template         */
line = "04Mark0005Twain"
parse var line len +2 first >(len) len +2 middle >(len) len +2 last >(len)
say '"'first'" "'middle'" "'last'"'  -- displays "Mark" "" "Twain"

/* parsing with relative patterns only */
parse var line len +2 first +(len) len +2 middle +(len) len +2 last +(len)
say '"'first'" "'middle'" "'last'"'  -- displays "Mark" "05Twain" "Twain"

The < length pattern will move the position to the left, and split the string between the original position and the movement position. At the end of the operation, the current position is returned to the original position. This movement is equivalent to using a negative relative pattern followed by a positive relative pattern for the same length. This operation allows for easy extraction of characters that precede a string match.
Example 9.13. Parsing with length patterns
/* Parsing with length patterns in template         */
parse value '12345.6789' with '.' digit <1    -- digit -> "5"

/* parsing with relative patterns only */
parse value '12345.6789' with '.' -1 digit +1    -- digit -> "5"