2012-07-17 155 views
1

我在查找指定子串出现的字符串中的位置。在COBOL中查找子串的索引

例如,寻找在串子串“环保”,“绿色鸡蛋和火腿”应该返回我1,但是从“绿色鸡蛋和火腿绿色”将返回我1和14

我应该如何做这个?

编辑1:改变措辞如此位置1开始,不是0 编辑2:我可以在下面的代码片段的第一个实例为WS-指针:

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     
+0

如果你正在寻找一个COBOL动词(陈述)来做到这一点,我认为你可能会运气不好。原生COBOL不会很好地执行子串:-( – NealB 2012-07-17 21:46:34

回答

3

AFAIK COBOL没有一条语句来查找字符串中字符串的位置,以便需要手动完成。然而,COBOL确实有一个统计字符串中的字符串出现一种说法: INSPECT串计数器清点所有搜索字符串

下面是一个例子程序,在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 ' ' 
     . 
+0

“UNTIL SEARCH-INDEX = 30”是不好的,你有一个30字节的字段,一旦你达到27,你就会看到你的表的“外部”知道OpenCobol如何“对齐”01,但如果IBM Enterprise Cobol和字段长度为32,那么如果第一个字符的第32个字符是“g”,而第二个字符的第四个字符是“reen”,则会得到“命中”。 – 2013-01-21 01:34:33

0

您可以在IBM使用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 
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执行。

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

相反,它是一个简单的任务,其中“substring”处理取决于或引用修改(接受的答案中的方法)。

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