在COBOL中查找子字符串的索引

时间:2012-07-17 18:00:15

标签: string indexing substring cobol

我正在寻找发生指定子字符串的字符串中的位置。

例如,在字符串“green eggs and ham”中查找子字符串“green”应该返回1,但是从“green eggs and green ham”中返回1和14。

我该怎么做?

编辑1:更改了措辞,因此位置从1开始,而不是0。 编辑2:我可以在下面的代码片段中找到第一个实例作为WS-POINTER:

 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                   

3 个答案:

答案 0 :(得分:3)

AFAIK COBOL没有声明来查找字符串中字符串的位置,因此需要手动完成。但是,COBOL确实有一个语句来计算字符串中字符串的出现次数: INSPECT string TALLYING计数器FOR ALL search-string

以下是一个在OpenCOBOL中运行的示例程序(请参阅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 ' '
       .

答案 1 :(得分:0)

您可以在IBM i上使用QCLSCAN

 77  QCLSCAN-SRCHLEN          PIC S9(3)     COMP-3.           
 77  QCLSCAN-STARTPOS         PIC S9(3)     COMP-3.           
 77  QCLSCAN-PATLEN           PIC S9(3)     COMP-3.           
 77  QCLSCAN-XLATE            PIC X(01)     VALUE "0".        
 77  QCLSCAN-TRIM             PIC X(01)     VALUE "0".        
 77  QCLSCAN-WILDCARD         PIC X(01)     VALUE LOW-VALUES. 
 77  QCLSCAN-FOUNDPOS         PIC S9(3)     COMP-3.           
 ...
 ...
     MOVE LENGTH OF WRK-ACCT-NBR TO QCLSCAN-SRCHLEN 
     MOVE     1                  TO QCLSCAN-STARTPOS
     MOVE     9                  TO QCLSCAN-PATLEN  
     MOVE "0"                    TO QCLSCAN-XLATE   
     MOVE "0"                    TO QCLSCAN-TRIM    
     MOVE "?"                    TO QCLSCAN-WILDCARD
     CALL "QCLSCAN" USING  WRK-ACCT-NBR             
                           QCLSCAN-SRCHLEN          
                           QCLSCAN-STARTPOS         
                           EMPLOYEE-SSN-9X          
                           QCLSCAN-PATLEN           
                           QCLSCAN-XLATE            
                           QCLSCAN-TRIM             
                           QCLSCAN-WILDCARD         
                           QCLSCAN-FOUNDPOS         
     IF QCLSCAN-FOUNDPOS > ZERO                     
* Found data in position QCLSCAN-FOUNDPOS
     ELSE
* Found no match
     END-IF

答案 2 :(得分:0)

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  

您询问如何将上述内容用于后续字符串。

可以通过两种方式使用UNSTRING来获得所需的计数。通过使用多个接收字段和COUNT-IN,或者每次使用前一个UNSTRING的POINTER值多次执行UNSTRING。

您需要考虑分隔符的长度。但是,您最终会得到“非直观”代码,每当有人拿起程序时,都必须“理解”这些代码。

相反,这是一个简单的任务,使用“子串”处理,使用OCCURS DEPENDING ON或引用修改(接受的答案中的方法)。

必须必须确保不“超出字段的结尾”搜索范围。