EXAMINE

#### Search Results

Search

# EXAMINE

This document covers the following topics:

- Syntax 1 - EXAMINE

- Syntax 2 - EXAMINE TRANSLATE

- Syntax 3 - EXAMINE for Unicode Graphemes

- EXAMINE Examples

Related Statements: `ADD` | `COMPRESS` | `COMPUTE` | `DIVIDE` | `MOVE` | `MOVE ALL` | `MULTIPLY` | `RESET` | `SEPARATE` | `SUBTRACT`

Belongs to Function Group: Arithmetic and Data Movement Operations

## Syntax 1 - EXAMINE

`EXAMINE` | [DIRECTION-clause]
| [`FULL` [`VALUE` [`OF`]]] |  | operand1 |
| `SUBSTRING` (operand1,operand2,operand3)
| [POSITION-clause] |  |
| [`FOR`] [`FULL` [`VALUE` [`OF`]]] [`PATTERN`] operand4
| [DELIMITERS-option]
| DELETE-REPLACE-clause |
GIVING-clause
DELETE-REPLACE-clause GIVING-clause

For an explanation of the symbols used in the syntax diagram, see Syntax Symbols.

### Syntax Description - Syntax 1

The `EXAMINE` statement is used to inspect the content of an alphanumeric or binary field, or a range of fields within an array, and to

- return the number of how many times a search-pattern was found;

- return the byte position where a search-pattern appears first;

- return the significant content length of a field; that is, the field length without trailing blanks;

- return the occurrence number (indices) of an array field, where a pattern was found first;

- replace a pattern by another pattern;

- delete a pattern.

Operand Definition Table:

Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition
--- | --- | --- | --- | ---
`operand1` | C* | S | A |  |  | A | U |  |  |  |  | B |  |  |  |  |  |  | yes | no
`operand2` | C | S |  |  |  |  |  | N | P | I |  | B* |  |  |  |  |  |  | yes | no
`operand3` | C | S |  |  |  |  |  | N | P | I |  | B* |  |  |  |  |  |  | yes | no
`operand4` | C | S | A* |  |  | A | U |  |  |  |  | B |  |  |  |  |  |  | yes | no

* `operand1` can only be a constant if the `GIVING` clause is used, but not if the `DELETE`/`REPLACE` clause is used.

* `operand4` can also be used as an array, see Search and Replace with Multiple Values.

* Format B of `operand2` and operand3 may be used only with a length of less than or equal to 4.

Syntax Element Description:

Syntax Element | Description
--- | ---
`DIRECTION-clause` | DIRECTION Clause: This clause determines the search direction. For details, see DIRECTION Clause below.
`operand1` | Field to be Examined: `operand1` is the field whose content is to be examined. If `operand1` is a `DYNAMIC` variable, a `REPLACE` operation may cause its length to be increased or decreased; a `DELETE` operation may cause its length to be set to zero. The current length of a `DYNAMIC` variable can be ascertained by using the system variable `*LENGTH`. For general information on `DYNAMIC` variables, see the section Large and Dynamic Variables/Fields.
`POSITION-clause` | POSITION Clause: This clause may be used to specify a starting and ending position within `operand1` (or the substring of `operand1`) for the examination. For details, see POSITION Clause below.
`operand4` | Value to be Used for EXAMINE Operation: `operand4` is the value which is searched for in the examined field(s). You may search for a single value or for multiple values. For more information on `operand4` and `operand6`, see `operand6`, which is used in the DELETE REPLACE Clause described below.
`FULL` | FULL Option: If `FULL` is specified for an operand, the entire value, including trailing blanks, will be processed. If `FULL` is not specified, trailing blanks in the operand will be ignored.
`SUBSTRING` | SUBSTRING Option: Normally, the content of a field is examined from the beginning of the field to the end or to the last non-blank character. With the `SUBSTRING` option, you examine only a certain part of the field. After the field name (`operand1`) in the `SUBSTRING` clause, you specify first the starting position (`operand2`) and then the length (`operand3`) of the field portion to be examined. For example, to examine the 5th to 12th position inclusive of a field #A, you would specify:
    EXAMINE SUBSTRING(#A,5,8).
Notes: If you omit `operand2`, the starting position is assumed to be `1`. If you omit `operand3`, the length is assumed to be from the starting position to the end of the field. If `SUBSTRING` is used in conjunction with a `DYNAMIC` variable, the field behaves like a fixed length variable; that is, the length (`*LENGTH`) does not change as a result of the `EXAMINE` operation, regardless of whether a `DELETE` or `REPLACE` operation was executed or not.
`PATTERN` | PATTERN Option: If you wish to examine the field for a value which contains "wild characters", that is symbols for positions not to be examined, you use the `PATTERN` option. `operand4` may then include the following symbols for positions to be ignored: A period (.), question mark (?) or underscore (_) indicates a single position that is not to be examined. An asterisk (*) or a percent sign (%) indicates any number of positions not to be examined. Example: With `PATTERN 'NAT*AL'` you could examine the field for any value which contains `NAT` and `AL` no matter which and how many other characters are between `NAT` and `AL` (this would include the values `NATURAL` and `NATIONAL` as well as `NATAL`). Note: If you use a pattern that starts with an asterisk (*) or percent sign (%), the following rule applies: All positions from the previous delimiter are not examined. If there is no delimiter, all positions from the beginning of the string are not examined. If you use a pattern that ends with an asterisk (*) or percent sign (%), the following rule applies: All positions to the next delimiter are not examined. If there is no delimiter, all positions to the end of the string are not examined.
`DELIMITERS-option` | DELIMITERS Option: This option is used to scan for a value which exhibits delimiters. For details, see DELIMITERS Option below.
`DELETE-REPLACE-clause` | DELETE REPLACE Clause: The `DELETE` option of this clause is used to delete each search-value (`operand4`) found in `operand1`, whereas the `REPLACE` option is used to replace each search-value (`operand4`) found in `operand1` by the value specified in `operand6`. For details, see DELETE REPLACE Clause below.
`GIVING-clause` | For details, see GIVING Clause below.

#### DIRECTION Clause

The direction clause determines the search direction.

|  | `FORWARD` |
`DIRECTION` | `BACKWARD`
| operand8

#### Operand Definition Table:

Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition
--- | --- | --- | --- | ---
`operand8` | C | S |  |  |  | A1 |  |  |  |  |  |  |  |  |  |  |  | yes | no

Syntax Element Description:

Syntax Element | Description
--- | ---
`FORWARD` | Examine in Left-to-Right Direction: If you specify `FORWARD`, the contents of the field are examined from left to right.
`BACKWARD` | Examine in Right-to-Left Direction: If you specify `BACKWARD`, the contents of the field are examined from right to left.
`operand8` | Alternative Specification: If you specify `operand8`, the search direction is determined by the contents of `operand8`. `operand8` must be defined with format/length A1. If `operand8` contains an `F`, then the search direction is `FORWARD`, if `operand8` contains a `B`, the search direction is `BACKWARD`. All other values are invalid and are rejected at compile time if `operand8` is a constant, or at run time if `operand8` is a variable.

Note
If the `DIRECTION` clause is not specified, the default direction is `FORWARD`.

#### POSITION Clause

The `POSITION` clause may be used to specify a starting and ending position within `operand1` (or the substring of `operand1`) for the examination.

[[`STARTING`] `FROM` [`POSITION`] operand9] |  |  | `ENDING AT` |  | [`POSITION`] operand10 |
`THRU`

Operand Definition Table:

Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition
--- | --- | --- | --- | ---
`operand9` | C | S |  |  |  |  | N | P | I |  |  |  |  |  |  |  |  | yes | no
`operand10` | C | S |  |  |  |  | N | P | I |  |  |  |  |  |  |  |  | yes | no

Syntax Element Description:

Syntax Element | Description
--- | ---
`FROM` `operand9` | Starting Position: `operand9` is used to define the starting position for the examination.
`ENDING AT / THRU operand10` | Ending Position: `operand10` is used to define the ending position for the examination.

The starting position (`operand9`) and the ending position (`operand10`) are relative to `operand1` or the substring of `operand1`, and both are processed.

The search is performed starting from the starting position and ending at the ending position.

If the starting and/or ending position are not specified, the default position value applies. This value is determined by the search direction:

Direction | Default Starting Position | Default Ending Position
--- | --- | ---
`FORWARD` | 1 (first character) | length of `operand1` (last character)
`BACKWARD` | length of `operand1` (last character) | 1 (first character)

Note
If the search direction is `FORWARD` and the start position is greater than the end position, or if the search direction is `BACKWARD` and the start position is less than the end position, no search is performed.

#### DELIMITERS Option

| `ABSOLUTE` |
`WITH [DELIMITERS`] [operand5]

Operand Definition Table:

Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition
--- | --- | --- | --- | ---
`operand5` | C | S |  |  |  | A | U |  |  |  |  | B |  |  |  |  |  |  | yes | no

Syntax Element Description:

Syntax Element | Description
--- | ---
`ABSOLUTE` | Absolute Scan Option: This is the default option. It results in an absolute scan of the field for the specified value regardless of what other characters may surround the value.
`WITH DELIMITERS` | WITH DELIMITERS Option: This option is used to scan for a value which is delimited by blanks or by any character that is neither a letter nor a numeric character.
`WITH DELIMITERS operand5` | Specific Delimiter Option: This option is used to scan for a value which is delimited by the character or any of the characters specified in `operand5`. If the search value was found at the beginning or end of the examined field, only the right or left side has to be delimited by one of the `operand5` characters.

#### DELETE/REPLACE Clause

[`AND`] |  | `DELETE` [`FIRST`] |
`REPLACE` [`FIRST`] [`WITH`] [`FULL` [`VALUE` [`OF`]]] operand6

Operand Definition Table:

Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition
--- | --- | --- | --- | ---
`operand6` | C | S | A* |  |  | A | U |  |  |  | B |  |  |  |  |  |  | yes | no

* `operand6` can also be used as an array, see Search and Replace with Multiple Values.

Syntax Element Description:

Syntax Element | Description
--- | ---
`DELETE` | DELETE Option: This option is used to delete the first (or all) occurrence(s) of the search-value (`operand4`) in the content of `operand1`.
`REPLACE` | REPLACE Option: This option is used to replace the first (or all) occurrence(s) of the search-value (`operand4`) in `operand1` by the replace value specified in `operand6`.
`FIRST` | FIRST Option: If you specify the keyword `FIRST`, only the first identical value will be deleted/replaced.

Notes:

1. If the `REPLACE` operation results in more characters being generated than will fit into `operand1`, you will receive an error message.
2. If `operand1` is a dynamic variable, a `REPLACE` operation may cause its length to be increased or decreased; a `DELETE` operation may cause its length to be set to zero. The current length of a dynamic variable can be ascertained by using the system variable `*LENGTH`. For general information on dynamic variables, see Using Dynamic Variables.

#### Search and Replace with Multiple Values

The search (`operand4`) and replace value (`operand6`) may also be defined as array fields. This allows to substitute multiple different patterns in the examined field (`operand1`), all with an unique `EXAMINE` statement. It is not necessary to have the same number of occurrences for the search and replace operand. All what is required is the transfer compatibility between these fields; that is, `operand4:=operand6` must be a valid operation; see Assignment Operations with Arrays in the Programming Guide.

The operation logic for the multi-value search is as follows:

- The field to be examined (`operand1`) is passed through only a single time, either from left to right for direction `FORWARD` or from right to left for direction `BACKWARD`.

- Beginning with the first position, the values in the search array (`operand4`) are tested for a match, one after the other, starting with the array occurrence with the lowest index.

- If no search value was found, the comparison repeats on the next field position.

- If one of the searched patterns is detected in the examined field (`operand1`), it is substituted with the value of the replace array (`operand6`), which overlays the matching pattern in `operand4`, if a `operand4:=operand6` would be executed.

- After a pattern replacement was performed, the compare process continues with the first occurrence for the search array, immediately after the inserted value. This means, a replaced pattern is skipped and may not be replaced a second time.

Example:

This example shows an HTML translation for the characters less than (<), greater than (>), and ampersand (&).

    DEFINE DATA LOCAL
    1 #HTML  (A/1:3) DYNAMIC INIT <'&lt;','&gt;','&amp;'>
    1 #TAB   (A/1:3) DYNAMIC INIT <'<','>','&'>
    1 #DOC(A) DYNAMIC  /* document to be replaced
    END-DEFINE
    #DOC := 'a&lt;&lt;b&amp;b&gt;c&gt;'
    WRITE #DOC (AL=30) 'before'
    /* Replace #DOC using #HTML to #TAB (n:1 replacement)
    EXAMINE   #DOC FOR  #HTML(*)  REPLACE  #TAB(*)
    /* '&lt;'  is replaced by '<'  (4:1 replacement)
    /* '&gt;'  is replaced by '>'  (4:1 replacement)
    /* '&amp;' is replaced by '&'  (5:1 replacement)
    WRITE #DOC (AL=30) 'after'
    END

See also Example 3 - EXAMINE AND REPLACE WITH MULTIPLE VALUES.

#### GIVING Clause

|  | `GIVING` [`IN`] operand7 |  |
[`GIVING`] `NUMBER` [`IN`] operand7
[[`GIVING`] `POSITION` [`IN`] operand7]
[[`GIVING`] `LENGTH` [`IN`] operand7]
[[`GIVING`] `INDEX` [`IN`] operand7 ...3]

Operand Definition Table:

Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition
--- | --- | --- | --- | ---
`operand7` |  | S |  |  |  |  | N | P | I |  |  |  |  |  |  |  |  | yes | yes

Syntax Element Description:

Syntax Element | Description
--- | ---
`GIVING` | GIVING Clause: If only the keyword `GIVING` is specified, this corresponds to `GIVING NUMBER` (default).
`NUMBER` | GIVING NUMBER Clause: Is used to obtain information on how many times the search value (`operand4`) was found in the field (`operand1`) whose content is to be examined.
`POSITION` | GIVING POSITION Clause: Is used to obtain the byte position within `operand1` (or the substring of `operand1`) where the first value identical to `operand4` was found.
`LENGTH` | GIVING LENGTH Clause: Is used to obtain the remaining content length of `operand1` (or the substring of `operand1`) after all delete/replace operations have been performed. Trailing blanks are ignored.
`operand7` | Number of Occurrences: The number of occurrences of the search-value. If the `REPLACE FIRST` or `DELETE FIRST` option is also used, the number will not exceed 1.
`INDEX operand7 ...3` | GIVING INDEX Clause: This option is only applicable if the underlying field to be examined is an array field. `GIVING INDEX` is used to obtain the array occurrence number (index) of `operand1` in which the first search-value (`operand4`) was found. `operand7` must be specified as many times as there are dimensions in operand1 (maximum three times). `operand7` will return `0` if the search-value is found in none of the occurrences. Note If the index range of `operand1` includes the occurrence `0` (for example, `0:5`), a value of `0` in `operand7` is ambiguous. In this case, an additional `GIVING NUMBER` clause should be used to ascertain whether the search-value was actually found or not.

## Syntax 2 - EXAMINE TRANSLATE

`EXAMINE` |  | operand1 |  | [`AND`]
`SUBSTRING` | (operand1,operand2,operand3)
|  | `TRANSLATE` |  | `INTO` |  | `UPPER` |  | [`CASE`] |  |
|  | `LOWER` |
|  | `USING` [`INVERTED`] `` operand4 |

For an explanation of the symbols used in the syntax diagram, see Syntax Symbols.

### Syntax Description - Syntax 2

The `EXAMINE TRANSLATE` statement is used to translate the characters contained in a field into upper-case or lower-case, or into other characters.

Operand Definition Table:

Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition
--- | --- | --- | --- | ---
`operand1` |  | S | A |  |  | A | U |  |  |  |  | B |  |  |  |  |  |  | yes | no
`operand2` | C | S |  |  |  |  |  | N | P | I |  | B* |  |  |  |  |  |  | yes | no
`operand3` | C | S |  |  |  |  |  | N | P | I |  | B* |  |  |  |  |  |  | yes | no
`operand4` |  | S | A |  |  | A | U |  |  |  |  | B |  |  |  |  |  |  | yes | no

*Format B of `operand2` and `operand3` may be used only with a length of less than or equal to 4.

Syntax Element Description:

Syntax Element | Description
--- | ---
`EXAMINE operand1` | Complete Field Content Translation: `operand1` is the field whose content is to be translated.
`EXAMINE SUBSTRING` `operand1` `operand2` `operand3` | Partial Field Content Translation: Normally, the entire content of a field is translated. With the `SUBSTRING` option, you translate only a certain part of the field. After the field name (`operand1`) in the `SUBSTRING` clause, you specify first the starting position (`operand2`) and then the length (`operand3`) of the field portion to be examined. For example, to translate the 5th to 12th position inclusive of a field `#A`, you would specify:
    EXAMINE SUBSTRING(#A,5,8) AND TRANSLATE ...
Note If you omit `operand2`, the starting position is assumed to be `1`. If you omit `operand3`, the length is assumed to be from the starting position to the end of the field.
`TRANSLATE INTO UPPER CASE` | Upper Case Translation: The content of `operand1` will be translated into upper case.
`TRANSLATE INTO LOWER CASE` | Lower Case Translation: The content of `operand1` will be translated into lower case.
`TRANSLATE USING operand4` | Translation Table: `operand4` is the translation table to be used for character translation. The table must be of format/length A2, U2 or B2. Note If for a character to be translated more than one translation is defined in the translation table, the last of these translations applies.
`INVERTED` | INVERTED Option: If you specify the keyword `INVERTED`, the translation table (`operand4`) will be used inverted; that is, the translation direction will be reversed.

## Syntax 3 - EXAMINE for Unicode Graphemes

`EXAMINE` [`FULL` [`VALUE` [`OF`]]] |  | `operand1` `SUBSTRING` (`operand1,operand2,operand3`) |
[`POSITION-clause`] |
[`FOR`] |  | `CHARPOSITION` operand4 `CHARLENGTH` operand5 `CHARPOSITION` operand4 `CHARLENGTH` operand5 |
| [`GIVING`] `POSITION` [`IN`] `operand6` [`GIVING`] `LENGTH` [`IN`] `operand7` |
[`GIVING`] `POSITION` [`IN`] `operand6`
[`GIVING`] `LENGTH` [`IN`] `operand7`

For an explanation of the symbols used in the syntax diagram, see Syntax Symbols.

### Syntax Description - Syntax 3

A "grapheme" is what a user normally thinks of as a character. In most cases, a UTF-16 code unit (= U format character) is a grapheme, however, a grapheme can also consist of several code units. Examples are: a sequence of a base character followed by combining characters or a surrogate pair. For more information on graphemes and other Unicode terms, see The Unicode Standard at http://www.unicode.org/.

The `EXAMINE` statement for U format operands in general operates on code units. However, with the `CHARPOSITION` and `CHARLENGTH` clauses it is possible to obtain the starting position and length (in terms of code units) of a graphemes sequence. The returned code unit values can then be used in other statements/clauses which require code unit operands (for example, in a `SUBSTRING` clause).

For further information on this syntax of the `EXAMINE` statement, see also Unicode and Code Page Support in the Natural Programming Language, section Statements, EXAMINE.

Operand Definition Table:

Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition
--- | --- | --- | --- | ---
`operand1` | C | S | A |  |  | U |  |  |  |  |  |  |  |  |  |  |  | yes | no
`operand2` | C | S |  |  |  |  | N | P | I |  | B* |  |  |  |  |  |  | yes | no
`operand3` | C | S |  |  |  |  | N | P | I |  | B* |  |  |  |  |  |  | yes | no
`operand4` | C | S |  |  |  |  | N | P | I |  |  |  |  |  |  |  |  | yes | no
`operand5` | C | S |  |  |  |  | N | P | I |  |  |  |  |  |  |  |  | yes | no
`operand6` |  | S |  |  |  |  | N | P | I |  |  |  |  |  |  |  |  | yes | no
`operand7` |  | S |  |  |  |  | N | P | I |  |  |  |  |  |  |  |  | yes | no

* Format B of `operand2` and `operand3` may be used only with a length of less than or equal to 4.

Syntax Element Description:

Syntax Element | Description
--- | ---
`FULL` | FULL Option: If `FULL` is specified for an operand, the entire value, including trailing blanks, will be processed. If `FULL` is not specified, trailing blanks in the operand will be ignored.
`SUBSTRING` `operand1` `operand2` `operand3` | SUBSTRING Clause: Normally, the content of a field is examined from the beginning of the field to the end or to the last non-blank character. With the `SUBSTRING` option, you examine only a certain part of the field. After the field name (`operand1`) in the `SUBSTRING` clause, you specify first the starting position (`operand2`) and then the length (`operand3`) of the field portion to be examined. `operand2` and `operand3` are specified in terms of code units. For example, to examine the 5th to 12th position inclusive of a field `#A`, you would specify:
    EXAMINE SUBSTRING (#A,5,8)
Notes: If you omit `operand2`, the starting position is assumed to be `1`. If you omit `operand3`, the length is assumed to be from the starting position to the end of the field. If `SUBSTRING` is used in conjunction with a `DYNAMIC` variable, the field behaves like a fixed length variable; that is, the length (`*LENGTH`) does not change as a result of the `EXAMINE` operation, regardless of whether a `DELETE` or `REPLACE` operation was executed or not.
`POSITION-clause` | POSITION Clause: `FROM` and `THRU` positions are given in terms of code units. For further information, see POSITION Clause under Syntax 1.
`CHARPOSITION operand4` | CHARPOSITION Clause: `operand4` defines the starting position (in terms of Unicode graphemes) of the grapheme sequence. The according position in terms of code units is returned in `operand6`. This clause can be omitted if the `CHARLENGTH` clause is specified; in this case the starting position 1 is assumed.
`CHARLENGTH operand5` | CHARLENGTH Clause: `operand5` defines the length (in terms of Unicode graphemes) of the grapheme sequence. The length of the grapheme sequence in terms of code units is returned in `operand7`. This clause can be omitted if the `CHARPOSITION` clause is specified; in this case the length from the starting position up to the end of the string is returned.
`GIVING POSITION IN operand6` | GIVING POSITION Clause: `operand6` receives the starting position (in terms of code units) of the grapheme sequence defined by `operand4` and `operand5`. If `operand1` has less than `operand4` graphemes, 0 is returned. This clause can be omitted if the `GIVING LENGTH` clause is specified.
`GIVING LENGTH IN operand7` | GIVING LENGTH Clause: `operand7` receives the length (in terms of code units) of the grapheme sequence defined by `operand4` and `operand5`. If `operand1` has less than `operand4`+`operand5` graphemes, 0 is returned. This clause can be omitted if the `GIVING POSITION` clause is specified.

Notes:

1. Either the `CHARPOSITION` or the `CHARLENGTH` clause or both must be specified.
2. Either the `GIVING POSITION` or `GIVING LENGTH` clause or both must be specified.

## EXAMINE Examples

- Example 1 - EXAMINE

- Example 2 - EXAMINE TRANSLATE

- Example 3 - EXAMINE AND REPLACE WITH MULTIPLE VALUES

- Example 4 - EXAMINE for Unicode Graphemes

### Example 1 - EXAMINE

    ** Example 'EXMEX1': EXAMINE
    ************************************************************************
    DEFINE DATA LOCAL
    1 #TEXT   (A45)
    1 #ARRAY  (A5/1:3)
    1 #A      (A3)
    1 #START  (N2)
    1 #NUM    (N2)
    1 #NUM1   (N2)
    1 #NUM2   (N2)
    1 #NUM3   (N2)
    1 #POS    (N2)
    1 #POS1   (N2)
    1 #LENG   (N2)
    1 #INDEX  (N2)
    END-DEFINE
    *
    MOVE 'ABC   A B C   .A.  .B.  .C.    -A-  -B-  -C- ' TO #TEXT
    *
    WRITE / 'EXAMPLE 1  (DELIMITER, GIVING NUMBER)'
    WRITE NOTITLE '#TEXT: ' #TEXT
    EXAMINE #TEXT FOR 'A' GIVING NUMBER #NUM1
    EXAMINE #TEXT FOR 'A' WITH DELIMITER GIVING NUMBER #NUM2
    EXAMINE #TEXT FOR 'A' WITH DELIMITER '.' GIVING NUMBER #NUM3
    WRITE 'EXAMINE #TEXT FOR "A" ' 57T 'Number found:' #NUM1
    WRITE 'EXAMINE #TEXT FOR "A" WITH DELIMITER' 57T 'Number found:' #NUM2
    WRITE 'EXAMINE #TEXT FOR "A" WITH DELIMITER "."'
      57T 'Number found:' #NUM3
    *
    WRITE / 'EXAMPLE 2  (DELIMITER, REPLACE, GIVING NUMBER)'
    WRITE 'EXAMINE #TEXT FOR "A" WITH DELIMITER "-" REPLACE WITH "*"'
    WRITE 'Before:' #TEXT
    EXAMINE #TEXT FOR 'A' WITH DELIMITER '-' REPLACE WITH '*'
            GIVING NUMBER #NUM
    WRITE 'After: ' #TEXT 57T 'Number found:' #NUM
    *
    *
    NEWPAGE
    *
    WRITE / 'EXAMPLE 3  (REPLACE, GIVING NUMBER)'
    WRITE 'EXAMINE      #TEXT FOR " " REPLACE WITH "+"'
    WRITE 'Before:' #TEXT
    EXAMINE #TEXT FOR ' ' REPLACE WITH '+' GIVING NUMBER #NUM
    WRITE 'After: ' #TEXT 57T 'Number found:' #NUM
    *
    WRITE / 'EXAMPLE 4  (FULL, REPLACE, GIVING NUMBER)'
    WRITE 'EXAMINE FULL #TEXT FOR " " REPLACE WITH "+"'
    WRITE 'Before:' #TEXT
    EXAMINE FULL #TEXT FOR ' ' REPLACE WITH '+' GIVING NUMBER #NUM
    WRITE 'After: ' #TEXT 57T 'Number found:' #NUM
    *
    WRITE / 'EXAMPLE 5  (DELETE, GIVING POSITION)'
    WRITE 'EXAMINE #TEXT FOR "+" DELETE GIVING POSITION #POS'
    WRITE 'Before:' #TEXT
    EXAMINE #TEXT FOR '+' DELETE GIVING POSITION #POS
    WRITE 'After: ' #TEXT 57T 'Position found:' #POS
    *
    WRITE / 'EXAMPLE 6  (DELETE, GIVING LENGTH)'
    WRITE 'EXAMINE #TEXT FOR "A" DELETE GIVING LENGTH #LENG'
    WRITE 'Before:' #TEXT
    EXAMINE #TEXT FOR 'A' DELETE GIVING LENGTH #LENG
    WRITE 'After: ' #TEXT 57T 'Length found:' #LENG
    *
    *
    NEWPAGE
    *
    MOVE 'ABC   A B C   .A.  .B.  .C.    -A-  -B-  -C- ' TO #TEXT
    *
    WRITE / 'EXAMPLE 7  (PATTERN, REPLACE, GIVING NUMBER)'
    WRITE 'EXAMINE #TEXT FOR         ".A." AND REPLACE "***"'
    WRITE 'Before:' #TEXT
    EXAMINE #TEXT FOR         '.A.' AND REPLACE '***' GIVING NUMBER #NUM
    WRITE 'After: ' #TEXT 57T 'Number found:' #NUM
    *
    MOVE 'ABC   A B C   .A.  .B.  .C.    -A-  -B-  -C- ' TO #TEXT
    *
    WRITE 'EXAMINE #TEXT FOR PATTERN ".A." AND REPLACE "***"'
    WRITE 'Before:' #TEXT
    EXAMINE #TEXT FOR PATTERN '.A.' AND REPLACE '***' GIVING NUMBER #NUM
    WRITE 'After: ' #TEXT 57T 'Number found:' #NUM
    *
    MOVE 'ABC   A B C   .A.  .B.  .C.    -A-  -B-  -C- ' TO #TEXT
    *
    #A   := 'B C'
    #POS := 6
    #LENG:= 25
    *
    WRITE / 'EXAMPLE 8  (SUBSTRING, REPLACE, GIVING POSITION)'
    WRITE '#A := "B C" ; #POS := 6 ; #LENG:= 25 '
    WRITE 'EXAMINE SUBSTRING(#TEXT,#POS,#LENG) FOR #A AND REPLACE "***"'
    WRITE 'Before:' #TEXT
    EXAMINE SUBSTRING(#TEXT,#POS,#LENG) FOR #A AND REPLACE '***'
            GIVING POSITION #POS1
    WRITE 'After: ' #TEXT 57T 'Position found:' #POS1
    *
    *
    NEWPAGE
    *
    MOVE 'ABC   A B C   .A.  .B.  .C.    -A-  -B-  -C- ' TO #TEXT
    *
    WRITE / 'EXAMPLE 9  (DELETE, GIVING NUMBER, GIVING POSITION, '-
            'GIVING LENGTH)'
    WRITE 'EXAMINE #TEXT FOR "." DELETE GIVING NUMBER   #NUM'
    WRITE 30T 'GIVING POSITION #POS'
    WRITE 30T 'GIVING LENGTH   #LENG'
    WRITE 'Before:' #TEXT
    EXAMINE #TEXT FOR '.' DELETE GIVING NUMBER #NUM
                                 GIVING POSITION #POS
                                 GIVING LENGTH   #LENG
    WRITE 'After: ' #TEXT
    WRITE 'Number found:  ' #NUM
    WRITE 'Position found:' #POS
    WRITE 'Length found:  ' #LENG
    *
    *
    *
    MOVE 'ABC  ' TO #ARRAY (1)
    MOVE '.A.B.' TO #ARRAY (2)
    MOVE '-A-B-' TO #ARRAY (3)
    *
    WRITE / 'EXAMPLE 10 (GIVING NUMBER, GIVING POSITION, GIVING INDEX)'
    WRITE '#ARRAY(1):' #ARRAY(1)
    WRITE '#ARRAY(2):' #ARRAY(2)
    WRITE '#ARRAY(3):' #ARRAY(3)
    WRITE 'EXAMINE #ARRAY(*) FOR "B" GIVING NUMBER   #NUM'
    WRITE 27T 'GIVING POSITION #POS'
    WRITE 27T 'GIVING INDEX    #INDEX'
    EXAMINE #ARRAY(*) FOR 'B' GIVING NUMBER   #NUM
                              GIVING POSITION #POS
                              GIVING INDEX    #INDEX
    WRITE 'Number found:  ' #NUM
    WRITE 'Position found:' #POS
    WRITE 'Index found:   ' #INDEX
    END

#### Output of Program EXMEX1:

    EXAMPLE 1  (DELIMITER, GIVING NUMBER)
    #TEXT:  ABC   A B C   .A.  .B.  .C.    -A-  -B-  -C-
    EXAMINE #TEXT FOR 'A'                                   Number found:   4
    EXAMINE #TEXT FOR 'A' WITH DELIMITER                    Number found:   3
    EXAMINE #TEXT FOR 'A' WITH DELIMITER '.'                Number found:   1

    EXAMPLE 2  (DELIMITER, REPLACE, GIVING NUMBER)
    EXAMINE #TEXT FOR 'A' WITH DELIMITER '-' REPLACE WITH '*'
    Before: ABC   A B C   .A.  .B.  .C.    -A-  -B-  -C-
    After:  ABC   A B C   .A.  .B.  .C.    -*-  -B-  -C-    Number found:   1

    EXAMPLE 3  (REPLACE, GIVING NUMBER)
    EXAMINE      #TEXT FOR ' ' REPLACE WITH '+'
    Before: ABC   A B C   .A.  .B.  .C.    -*-  -B-  -C-
    After:  ABC+++A+B+C+++.A.++.B.++.C.++++-*-++-B-++-C-    Number found:  20

    EXAMPLE 4  (FULL, REPLACE, GIVING NUMBER)
    EXAMINE FULL #TEXT FOR ' ' REPLACE WITH '+'
    Before: ABC+++A+B+C+++.A.++.B.++.C.++++-*-++-B-++-C-
    After:  ABC+++A+B+C+++.A.++.B.++.C.++++-*-++-B-++-C-+   Number found:   1

    EXAMPLE 5  (DELETE, GIVING POSITION)
    EXAMINE #TEXT FOR '+' DELETE GIVING POSITION #POS
    Before: ABC+++A+B+C+++.A.++.B.++.C.++++-*-++-B-++-C-+
    After:  ABCABC.A..B..C.-*--B--C-                        Position found:   4

    EXAMPLE 6  (DELETE, GIVING LENGTH)
    EXAMINE #TEXT FOR 'A' DELETE GIVING LENGTH #LENG
    Before: ABCABC.A..B..C.-*--B--C-
    After:  BCBC...B..C.-*--B--C-                           Length found:  21

    EXAMPLE 7  (PATTERN, REPLACE, GIVING NUMBER)
    EXAMINE #TEXT FOR         '.A.' AND REPLACE '***'
    Before: ABC   A B C   .A.  .B.  .C.    -A-  -B-  -C-
    After:  ABC   A B C   ***  .B.  .C.    -A-  -B-  -C-    Number found:   1
    EXAMINE #TEXT FOR PATTERN '.A.' AND REPLACE '***'
    Before: ABC   A B C   .A.  .B.  .C.    -A-  -B-  -C-
    After:  ABC  ***B C   ***  .B.  .C.    ***  -B-  -C-    Number found:   3

    EXAMPLE 8  (SUBSTRING, REPLACE, GIVING POSITION)
    #A := 'B C' ; #POS := 6 ; #LENG:= 25
    EXAMINE SUBSTRING(#TEXT,#POS,#LENG) FOR #A AND REPLACE '***'
    Before: ABC   A B C   .A.  .B.  .C.    -A-  -B-  -C-
    After:  ABC   A ***   .A.  .B.  .C.    -A-  -B-  -C-    Position found:   4

    EXAMPLE 9  (DELETE, GIVING NUMBER, GIVING POSITION, GIVING LENGTH)
    EXAMINE #TEXT FOR '.' DELETE GIVING NUMBER   #NUM
                                 GIVING POSITION #POS
                                 GIVING LENGTH   #LENG
    Before: ABC   A B C   .A.  .B.  .C.    -A-  -B-  -C-
    After:  ABC   A B C   A  B  C    -A-  -B-  -C-
    Number found:     6
    Position found:  15
    Length found:    38

    EXAMPLE 10 (GIVING NUMBER, GIVING POSITION, GIVING INDEX)
    #ARRAY(1): ABC
    #ARRAY(2): .A.B.
    #ARRAY(3): -A-B-
    EXAMINE #ARRAY(*) FOR 'B' GIVING NUMBER   #NUM
                              GIVING POSITION #POS
                              GIVING INDEX    #INDEX
    Number found:     3
    Position found:   2
    Index found:      1

### Example 2 - EXAMINE TRANSLATE

    ** Example 'EXMEX2': EXAMINE TRANSLATE
    ************************************************************************
    DEFINE DATA LOCAL
    1 #TEXT  (A50)
    1 #TAB   (A2/1:10)
    1 #POS   (N2)
    1 #LENG  (N2)
    END-DEFINE
    *
    MOVE 'ABC   A B C   .A.  .B.  .C.    -A-  -B-  -C- ' TO #TEXT
    *
    MOVE 'AX' TO #TAB(1)
    MOVE 'BY' TO #TAB(2)
    MOVE 'CZ' TO #TAB(3)
    *
    *
    WRITE NOTITLE / 'EXAMPLE 1  (WITH TRANSLATION TABLE)'
    WRITE 'EXAMINE #TEXT TRANSLATE USING #TAB(*)'
    WRITE 'Before:' #TEXT
    EXAMINE #TEXT TRANSLATE USING #TAB(*)
    WRITE 'After: ' #TEXT
    *
    WRITE / 'EXAMPLE 2  (WITH INVERTED TRANSLATION TABLE)'
    WRITE 'EXAMINE #TEXT TRANSLATE USING INVERTED #TAB(*)'
    WRITE 'Before:' #TEXT
    EXAMINE #TEXT TRANSLATE USING INVERTED #TAB(*)
    WRITE 'After: ' #TEXT
    *
    #POS := 13
    #LENG:= 15
    *
    WRITE / 'EXAMPLE 3  (WITH LOWER CASE TRANSLATION)'
    WRITE '#POS := 13 ; #LENG:= 15 '
    WRITE 'EXAMINE SUBSTRING(#TEXT,#POS,#LENG) TRANSLATE INTO LOWER CASE'
    WRITE 'Before:' #TEXT
    EXAMINE SUBSTRING(#TEXT,#POS,#LENG) TRANSLATE INTO LOWER CASE
    WRITE 'After: ' #TEXT
    *
    END

#### Output of Program EXMEX2:

    EXAMPLE 1  (WITH TRANSLATION TABLE)
    EXAMINE #TEXT TRANSLATE USING #TAB(*)
    Before: ABC   A B C   .A.  .B.  .C.    -A-  -B-  -C-
    After:  XYZ   X Y Z   .X.  .Y.  .Z.    -X-  -Y-  -Z-

    EXAMPLE 2  (WITH INVERTED TRANSLATION TABLE)
    EXAMINE #TEXT TRANSLATE USING INVERTED #TAB(*)
    Before: XYZ   X Y Z   .X.  .Y.  .Z.    -X-  -Y-  -Z-
    After:  ABC   A B C   .A.  .B.  .C.    -A-  -B-  -C-

    EXAMPLE 3  (WITH LOWER CASE TRANSLATION)
    #POS := 13 ; #LENG:= 15
    EXAMINE SUBSTRING(#TEXT,#POS,#LENG) TRANSLATE INTO LOWER CASE
    Before: ABC   A B C   .A.  .B.  .C.    -A-  -B-  -C-
    After:  ABC   A B C   .a.  .b.  .c.    -A-  -B-  -C-

### Example 3 - EXAMINE AND REPLACE WITH MULTIPLE VALUES

    *  EXAMPLE 'EXMEX3': EXAMINE AND REPLACE WITH MULTIPLE VALUES
    ************************************************************************
    * This example shows a translation of the pattern
    * 'AA', 'Aa' and 'aA' into '++',
    * 'BB', 'Bb' and 'bB' into '--' and
    * 'CC', 'Cc' and 'cC' into '**'.
    ************************************************************************
    DEFINE DATA LOCAL
    1 #SV     (A2/1:3,1:3) INIT (1,V) <'AA','BB','CC'>
                                (2,V) <'Aa','Bb','Cc'>
                                (3,V) <'aA','bB','cC'>
    1 #RV     (A2/1:3)     INIT       <'++','--','**'>
    1 #STRING (A20)        INIT <'AAABbbbbBCCCcccCaaaA'>
    1 #NUM    (N2)
    END-DEFINE
    *
    *
    WRITE NOTITLE / 'EXAMINE #STRING FOR #SV(*,*) AND REPLACE WITH #RV(*)' /
    *
    WRITE 'Before:' #STRING   /* shows   'AAABbbbbBCCCcccCaaaA'
    *
    EXAMINE #STRING FOR #SV(*,*) AND REPLACE WITH #RV(*)
            GIVING NUMBER #NUM
    *
    WRITE 'After: ' #STRING   /* shows   '++A--bb--****c**aa++'
      40T 'Number found:' #NUM
    *

#### Output of Program EXMEX3:

    EXAMINE #STRING FOR #SV(*,*) AND REPLACE WITH #RV(*)

    Before: AAABbbbbBCCCcccCaaaA
    After:  ++A--bb--****c**aa++           Number found:   7

### Example 4 - EXAMINE for Unicode Graphemes

This example demonstrates the analysis of a Unicode string containing the characters `ä` und `ü`. Both characters are defined as base character followed by a combining character: `ä` is coded with `U+0061` followed by `U+0308`, and `ü` is coded with `U+0075` followed by `U+0308`.

    DEFINE DATA LOCAL
    1 #U (U20)
    1 #START (I2)
    1 #POS (I2)
    1 #LEN (I2)
    END-DEFINE
    #U := U'AB'-UH'00610308'-U'CD'-UH'00750308'-U'EF'
    *
    REPEAT
      #START := #START + 1
      EXAMINE #U FOR CHARPOSITION #START
                       CHARLENGTH      1
                  GIVING POSITION IN #POS
                           LENGTH IN #LEN
    *
      INPUT (AD=O) MARK POSITION #POS IN FIELD *#U
        '         UNICODE-STRING:' #U     (AD=MI)
     // '          CHARACTER NO.:' #START (EM=9)
      / 'STARTS AT BYTE POSITION:' #POS   (EM=9)
      / '      AND THE LENGTH IS:' #LEN   (EM=9)
    WHILE #POS NE 0
    END-REPEAT
    END

Output:

z/OS Environments: | Windows and Linux Environments (with Natural Web I/O Interface):
--- | ---
    UNICODE-STRING: ABa?CDu?EF

              CHARACTER NO.: 1
    STARTS AT BYTE POSITION: 1
          AND THE LENGTH IS: 1
    UNICODE-STRING: ABäCDüEF

              CHARACTER NO.: 1
    STARTS AT BYTE POSITION: 1
          AND THE LENGTH IS: 1
Press ENTER to continue. | Press ENTER to continue.
    UNICODE-STRING: ABa?CDu?EF

              CHARACTER NO.: 2
    STARTS AT BYTE POSITION: 2
          AND THE LENGTH IS: 1
    UNICODE-STRING: ABäCDüEF

              CHARACTER NO.: 2
    STARTS AT BYTE POSITION: 2
          AND THE LENGTH IS: 1
Press ENTER to continue. | Press ENTER to continue.
Note that the character in position 3 is a combining character sequence and is two code units long.
    UNICODE-STRING: ABa?CDu?EF

              CHARACTER NO.: 3
    STARTS AT BYTE POSITION: 3
          AND THE LENGTH IS: 2
    UNICODE-STRING: ABäCDüEF

              CHARACTER NO.: 3
    STARTS AT BYTE POSITION: 3
          AND THE LENGTH IS: 2
And so on. | And so on.

### On this page

- Syntax 1 - EXAMINE
- Syntax 2 - EXAMINE TRANSLATE
- Syntax 3 - EXAMINE for Unicode Graphemes
- EXAMINE Examples