3

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

例如,在字符串“green eggs and ham”中寻找子字符串“green”应该返回 me 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                   
4

3 回答 3

3

AFAIK COBOL 没有在字符串中查找字符串位置的语句,因此需要手动完成。但是,COBOL 确实有一个语句可以计算字符串中字符串的出现次数:INSPECT string TALLYING counter 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 ' '
       .
于 2012-07-18T04:07:22.873 回答
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
于 2012-07-31T13:09:34.513 回答
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 的多次执行,每次都使用前一个 UNSTRING 的 POINTER 值。

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

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

当 count + length-of-delimiter = max-length-of-string-to-search 时结束搜索,您必须确保不会“超出字段末尾”。

于 2013-05-18T10:27:58.863 回答