INSPECT Statement

The INSPECT statement supports counting and modification of single characters or groups of characters within a data item. INSPECT performs its operations on strings and requires that the source data item be designated USAGE DISPLAY.

INSPECT performs three basic functions: TALLYING, REPLACING, and CONVERTING. (CONVERTING is a specialized, shorthand form of REPLACING).

Note: This manual entry includes code examples and highlights for first-time users following the General Rules section.

Format 1

INSPECT source

 [ TALLYING { counter FOR { { {ALL    } comp-val }
                            { {LEADING}          }
                            {     CHARACTERS     }

           [delim] } ... } ... ] ...

 [ REPLACING 

    { CHARACTERS BY repl-char [delim]        }
    { {ALL    }                              }
    { {LEADING} { targ BY repl [delim] } ... }
    { {FIRST  }                              }
                      ... ]

Format 2

INSPECT source
    CONVERTING comp-chars TO conv-chars  [delim]

delim has the following format:

    { {BEFORE} INITIAL delimiter } ...
      {AFTER }

Format 3

INSPECT source

    [ TALLYING counter FOR TRAILING comp-value ] 
    [ REPLACING TRAILING target BY replace ] 

Syntax Rules

  1. source is a data item with USAGE DISPLAY.
  2. counter is an elementary numeric data item.
  3. comp-val is a nonnumeric literal (other than an ALL literal) or an elementary alphabetic, alphanumeric, or numeric data item with USAGE DISPLAY.
  4. repl-char is a one-character item with the same restrictions as comp-val.
  5. targ, delimiter, repl, comp-chars, and conv-chars have the same restrictions as comp-val.
  6. In Formats 1 and 3, at least one of the TALLYING or REPLACING phrases must be specified.
  7. Any delim phrase may have no more than one AFTER and one BEFORE phrase in it.
  8. The sizes of the data referred to by targ and repl must be the same. If repl is a figurative constant, its size is set equal to the size of targ.
  9. When the CHARACTERS phrase of the REPLACING clause is used, delimiter (if specified) must have a data size of one character.
  10. The sizes of the data referred to by comp-chars and conv-chars must be the same. When conv-chars is a figurative constant, its size equals that of comp-chars.
  11. The same character cannot appear more than once in the data referred to by comp-chars.
  12. comp-value, target, and replace are nonnumeric literals or single-character alphanumeric data items.

General Rules

  1. Inspection starts at the leftmost character of source and proceeds character by character until it reaches the rightmost character.
  2. source, comp-val, delimiter, targ, repl, repl-char, comp-chars, and conv-chars are treated as if they were redefined by an alphanumeric elementary data item. The data referred to by these items is treated as a character string.
  3. If the size of source is zero characters, no inspection occurs.
  4. If the size of comp-val or targ is zero characters, no match in source by these items is successful.
  5. comp-val and targ are matched in the source string according to the following rules:
    1. Comparison starts at the leftmost character and proceeds character by character until the rightmost character of source is reached.
    2. The first comp-val or targ item is checked at the current character location for a match. A match occurs if every character of comp-val or targ is the same as the corresponding characters in source starting at the current character position.
    3. If no match occurs, successive comp-val or targ items are checked at the current character position until a match occurs or the list of items is exhausted. The next character position is then checked and the process repeats.
    4. When a match occurs, the specified tallying or replacement is performed. Further checking for matching items at this character position is not performed. The new next character position to use for matching is set to be the character to the immediate right of the rightmost character position that matched in the preceding comparison.
    5. Inspection halts when the rightmost character of source has served as the current matching character position or has been successfully matched in the preceding rule.
    6. When the CHARACTERS phrase is present, inspection proceeds as if a single-character value were being compared and it successfully matches every character in source.
  6. The BEFORE phrase modifies the character position to use as the rightmost position in source for the corresponding comparison operation. Comparisons in source occur only to the left of the first occurrence of delimiter. If delimiter is not present in source, then the comparison proceeds as if there were no BEFORE phrase.
  7. The AFTER phrase modifies the character position to use as the leftmost position in source for the corresponding comparison operation. Comparisons in source occur only to the right of the first occurrence of delimiter. This character position is the one immediately to the right of the rightmost character of the delimiter found. If delimiter is not found in source, the INSPECT statement has no effect (no tallying or replacement occurs).
  8. If both the TALLYING and REPLACING phrases are present, the TALLYING option is performed first, and then the REPLACING option is performed as if it were written as a separate INSPECT statement.
TALLYING Option
  1. The INSPECT statement does not initialize counter.
  2. If the ALL phrase is present, counter is incremented by one for each occurrence of comp-value in source.
  3. If the LEADING phrase is present, counter is incremented by one for each contiguous occurrence of comp-value in source. These occurrences must start at the position in source where comparison begins. Otherwise, no tallying occurs.
  4. If the CHARACTERS phrase is present, counter is incremented by one for each character in source that is matched (see General Rule 5f above).
  5. If the FOR TRAILING phrase is present, counter is incremented by one for each contiguous occurrence of comp-value in source, starting at the rightmost (trailing) character and scanning leftwards. If the rightmost character is not comp-value, then counter is not incremented.
REPLACING Option
  1. The adjectives ALL, LEADING, and FIRST apply to succeeding compare items until the next such adjective appears.
  2. If the CHARACTERS phrase is used, each character matched in source is replaced by the single character repl-char.
  3. When the ALL phrase is present, each occurrence of targ matched in source is replaced by repl.
  4. If the LEADING phrase is present, each contiguous occurrence of targ matched in source is replaced by repl. These occurrences must begin at the leftmost position in source used for comparison.
  5. When the FIRST phrase is present, the leftmost occurrence of targ matched in source is replaced by repl.
  6. If the TRAILING phrase is present, the REPLACING option causes all contiguous occurrences of target to be replaced by replace, provided that these occurrences end in the rightmost character position of source.
  7. It is possible for a size mismatch between the INSPECT and REPLACING data items to occur during program execution. This could happen when reference modification is used, because in that case the length of a data item is not known at compile time. If such a mismatch occurs, the runtime generates the INSPECT REPLACING size mismatch error. This error belongs to the intermediate class of runtime errors which call installed error procedures. See CBL_ERROR_PROC in Appendix I. Library Routines for details.
CONVERTING Option
  1. The CONVERTING form of the INSPECT statement has the effect of replacing every character in source found in comp-chars with the corresponding character in comp-chars. This is done according to the following rules:
    1. The INSPECT statement is treated as if it were specified with the REPLACING option containing a series of ALL phrases, one for each character of comp-chars.
    2. The targ item in each ALL phrase refers to a single character of comp-chars.
    3. The repl item in each ALL phrase refers to a single character of conv-chcomp-charsars.
    4. The individual characters of comp-chars and conv-chars correspond by ordinal position.
  2. INSPECT CONVERTING is usually more efficient than the corresponding INSPECT REPLACING statement.

Code Example 1

Use INSPECT to count the number of occurrences of a character or string:

01  CHAR-COUNT  PIC 99 VALUE 0.

*count all "b"s
INSPECT INPUT-ITEM
   TALLYING CHAR-COUNT FOR ALL "B".
Value of INPUT-ITEM CHAR-COUNT
#BB44@#AL23#AL88#xx#CC12 2
#BB@#BBBB#CCCC#xxDD 6
BB@#BB#BB 6
*count all "#"s found after the first "@"
*and before the first "x"
INSPECT INPUT-ITEM
  TALLYING CHAR-COUNT FOR ALL "#":
     AFTER "@" BEFORE "x".
Value of INPUT-ITEM CHAR-COUNT
#BB44@#AL23#AL88#xx#CC12 3
#BB@#BBBB#CCCC#xxDD 3
BB@#BB#BB 2
*count all characters
INSPECT INPUT-ITEM
   TALLYING CHAR-COUNT FOR CHARACTERS.
Value of INPUT-ITEM CHAR-COUNT
#BB44@#AL23#AL88#xx#CC12 24
#BB@#BBBB#CCCC#xxDD 19
BB@#BB#BB 9

Code Example 2

Use INSPECT to replace matching characters or strings:

INSPECT NAME-LIST REPLACING
*if the first characters in the string are "a"
*replace the "a"s with "A"s
   LEADING "a" BY "A"
*replace all "T"s found after the first "/"
*with "t"
   ALL "T" BY "t" AFTER "/"
*replace all "/"s with ":"
   ALL "/" BY ":"
*after the first "-" replace all characters 
*in the string with "Z"
   CHARACTERS BY "Z" AFTER "-". 
Input value NAME-LIST Output value NAME-LIST
TED/TRAVIS/UREY/VENNEY TED:tRAVIS:UREY:VENNEY
aVERY/BLAZE/TERI AVERY:BLAZE:tERI
MAVIS-GUS-HAL-WESTON MAVIS-ZZZZZZZZZZZZZZ

Code Example 3

Use INSPECT to both tally and replace characters or strings:

INSPECT PART-LIST
*count all "P-"
   TALLYING P-COUNT FOR ALL "P-"
*replace all "xx" by "__"
   REPLACING ALL "xx" BY "__".
   
Value of PART-LIST P-COUNT
P-BOLTxxP-WASHERxxP-NUT 3
Input value PART-LIST Output value PART-LIST
P-BOLTxxP-WASHERxxP-NUT P-BOLT__P-WASHER__P-NUT

Code Example 4

Use INSPECT/CONVERT to convert every occurrence of the specified characters in the input string (equivalent to a series of REPLACE ALL phrases). The list of characters following the words CONVERT and TO is not a string, but, rather, a list of individual characters. INSPECT/CONVERT replaces every occurrence of each character in the CONVERT list with the character in the matching ordinal position of the TO list. AFTER and BEFORE can be used to bracket a portion of the source string.

*convert all occurrences of:
*"-" to "0", "l" to "L",
*"a" to "A" and "/" to ":"
INSPECT PART-LIST
   CONVERTING "-la/" TO "0LA:".

This INSPECT/CONVERT statement is equivalent to:

INSPECT PART-LIST
   REPLACING ALL "-" BY "0"
             ALL "l" BY "L"
             ALL "a" BY "A"
             ALL "/" BY ":".
Input value PART-LIST Output value PART-LIST
Yla-1/Yla-2/Yla-3/Yla21 YLA01:YLA02:YLA03:YLA21

Highlights for First-time Users

  1. How the matching process works:

    In all formats of the INSPECT statement there must be a set of specified match values. The match values may be single characters or strings, or a mix of both. The match values are the arguments specified after the TALLYING/FOR, REPLACING, or CONVERTING key words, and before the BY or TO key words (for further clarification see the example that follows).

    INSPECT attempts to locate the match values in the source data item. The match values are searched for, in order of appearance in the code, at each position in the source string. Inspection starts at the leftmost character of the source data item and proceeds, character by character, to the rightmost character.

    Match process example:

    INSPECT source-data-item
      REPLACING "cd" BY "QP"
                "e"  BY "T"
                "f"  BY "V".

    Source data item: "abcdefg"

    Set of match values: "cd", "e", "f"

    The search begins at the leftmost character:

    "abcdefg"
     ^

    The first value in the match set is "cd". The first element, "c", is compared to the value "a" for a match. No match. The second value in the match set is "e". "e" is tested for a match with "a". No match. The third value in the match set is "f". "f" is tested for a match with "a". No match. There are no untested values remaining in the match set. The current position in the source data item is advanced one position to the right.

    "abcdefg"
      ^

    The sequential testing of the members of the match set to the value of the current position in the source data item is repeated. None matches. The current position in the source data item is advanced one position to the right.

    "abcdefg"
       ^

    The first match value is "cd". "c" is tested for a match with the current position in the source data item and there is a match. "d" is tested against the value of 1 + the current position ("d") and, again, there is a match. There are no more characters in the match value ("cd"). The first value in the match set results in a complete match at the current position in the source data item. Remaining values in the match set are not tested. The specified REPLACING action is performed. The current position in the source data item is advanced the length of the match value ("cd"), two places to the right.

    "abQPefg"
         ^

    Sequential testing of the members of the match set to the value of the current position in the source data item is repeated. The second member of the match set, "e", is a match. The REPLACING action is performed and the current position in the source data item is advanced the length of the match value, one position to the right.

    "abQPTfg"
          ^

    Notice that, if we had replaced "cd" with "ef" instead of "QP", the "e" and "f" would not be subsequently replaced with "T and "V". Sequential testing of the members of the match set to the value of the current position in the source data item is repeated. The third member of the match set, "f", is a match. The REPLACING action is performed and the current position in the source data item is advanced the length of the match value, one position to the right.

    "abQPTVg"
           ^
    Sequential testing of the members of the match set to the value of the current position in the source data item is repeated. None matches. The current position in the source data item is the rightmost character; therefore, the inspection halts. For a more concise description of the matching process, see General Rule 5 above.
  2. All replacement actions must replace the same number of characters as matched. The source data item may not change in size.
  3. Use AFTER and BEFORE to bracket (define) a substring in the source data item.
  4. Use ALL to match all occurrences of the specified value in the string.
  5. Use CHARACTERS to match every character in the source data item that hasn't already been matched. Because CHARACTERS matches all elements of the source data item, CHARACTERS usually appears as the last phrase in the statement.
  6. Use LEADING to find the leading occurrence, or set of leading contiguous occurrences, in the source data item.
  7. Use TRAILING (ACUCOBOL-GT extension) to find the rightmost occurrence, or set of contiguous occurrences, in the source data item. If a TRAILING occurrence is found, a right to left scan of the source data item is made to find contiguous occurrences.
  8. Use FIRST to specify a match of the first occurrence only.
  9. Many COBOL programming texts caution against writing involved and complicated INSPECT statements, because complex statements are difficult to understand and maintain.