Finding index of a substring in COBOL

20,815

AFAIK COBOL does not have a statement to find the position of a string within a string, so that needs to be done manually. However, COBOL does have a statement that counts the occurrences of a string within a string: INSPECT string TALLYING counter FOR ALL search-string

Here is an example program that works in OpenCOBOL (see OpenCobol.org):

   IDENTIFICATION DIVISION.
   PROGRAM-ID. OCCURRENCES.

   ENVIRONMENT DIVISION.
   INPUT-OUTPUT SECTION.
   FILE-CONTROL.

   DATA DIVISION.
   FILE SECTION.

   WORKING-STORAGE SECTION.
   01  TEST-STRING-1                    PIC X(30)
       VALUE 'green eggs and ham'.
   01  TEST-STRING-2                    PIC X(30)
       VALUE 'green eggs and green ham'.
   01  TEST-STRING                      PIC X(30).
   01  SEARCH-STRING                    PIC X(05)
       VALUE 'green'.
   01  MATCH-COUNT                      PIC 9.
   01  SEARCH-INDEX                     PIC 99.
   01  MATCH-POSITIONS.
       05  MATCH-POS                    PIC 99 OCCURS 9 TIMES.

   PROCEDURE DIVISION.
   MAIN.
       MOVE TEST-STRING-1 TO TEST-STRING
       PERFORM FIND-MATCHES

       MOVE TEST-STRING-2 TO TEST-STRING
       PERFORM FIND-MATCHES

       STOP RUN
       .

   FIND-MATCHES.
       MOVE ZERO TO MATCH-COUNT 
       INSPECT TEST-STRING TALLYING MATCH-COUNT
           FOR ALL SEARCH-STRING.
       DISPLAY 'FOUND ' MATCH-COUNT ' OCCURRENCE(S) OF '
           SEARCH-STRING ' IN:'
       DISPLAY TEST-STRING
       DISPLAY 'MATCHES FOUND AT POSITIONS: ' WITH NO ADVANCING
       PERFORM VARYING SEARCH-INDEX FROM 1 BY 1
           UNTIL SEARCH-INDEX = 30
           IF TEST-STRING (SEARCH-INDEX:5) = SEARCH-STRING
               DISPLAY SEARCH-INDEX ' ' WITH NO ADVANCING
       END-PERFORM
       DISPLAY ' '
       DISPLAY ' '
       .
Share:
20,815
Thalecress
Author by

Thalecress

Updated on July 09, 2022

Comments

  • Thalecress
    Thalecress almost 2 years

    I'm looking for the positions in a string where a specified substring occurs.

    E.g, looking for substring "green" in the the string "green eggs and ham" should return me 1, but from "green eggs and green ham" would return me 1 and 14.

    How should I do this?

    Edit 1: Changed the wording so position starts at 1, not 0. Edit 2: I can find the first instance as WS-POINTER in the following snippet:

     MOVE 1 TO  WS-POINTER
    
     UNSTRING WS-STRING(1:WS-STRING-LEN)
      DELIMITED BY LT-MY-DELIMITER
      INTO WS-STRING-GARBAGE                             
      WITH POINTER WS-POINTER
     END-UNSTRING