IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

Wildcard logic in COBOL


IBM Mainframe Forums -> COBOL Programming
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
dudenithy

New User


Joined: 02 Mar 2012
Posts: 48
Location: India

PostPosted: Thu Sep 01, 2016 7:36 pm
Reply with quote

Hello all,

I would like to know is there any efficient way of matching a value against a Parameter with multiple Wildcard mask "*"? For Parameter with multiple wildcard characters "?", and for a parameter with single symbol "*", it is simple. Now I have a challenge to cater multiple "*" in a parameter.

Example: 12*5*78. Values with 12578, 123578, 12345678 are accepted, but not like 123478, 125789, 1234567. Wildcard Symbol can be placed at any place of a value (*1234*, 12*5*78*9*, etc).
I have tried checking the efficient pseudo code, but couldn't get it icon_eek.gif .

Could anyone help or suggest? Thanks.
Back to top
View user's profile Send private message
dudenithy

New User


Joined: 02 Mar 2012
Posts: 48
Location: India

PostPosted: Mon Sep 05, 2016 3:49 pm
Reply with quote

Thanks for the above suggestions. Too simple, but unfortunately I cannot use it, since I have to do it in COBOL only icon_cry.gif.
I'm trying to build the logic in COBOL. This will work to a extent with some complicated Wildcard combinations must be restricted in Parameters. I will post when ready.
In the meantime, if anyone already smart have a logic in COBOl, always be welcome icon_biggrin.gif.
Back to top
View user's profile Send private message
Rohit Umarjikar

Global Moderator


Joined: 21 Sep 2010
Posts: 3076
Location: NYC,USA

PostPosted: Tue Sep 06, 2016 11:27 am
Reply with quote

Quote:
Thanks for the above suggestions. Too simple, but unfortunately I cannot use it, since I have to do it in COBOL only.
I'm trying to build the logic in COBOL. This will work to a extent with some complicated Wildcard combinations must be restricted in Parameters. I will post when ready.
May we know why? But then did you understand both the logic? What in cobol doesn't let you mimic the above logic?
Back to top
View user's profile Send private message
dudenithy

New User


Joined: 02 Mar 2012
Posts: 48
Location: India

PostPosted: Tue Sep 06, 2016 6:39 pm
Reply with quote

Rohit Umarjikar wrote:
May we know why? But then did you understand both the logic? What in cobol doesn't let you mimic the above logic?

It is because I'm not fit enough to understand all commands of above programming languages (though I could able to fairly understand the logic concept) and as said already, in between I'm mid of developing the code in COBOL itself.
Back to top
View user's profile Send private message
dudenithy

New User


Joined: 02 Mar 2012
Posts: 48
Location: India

PostPosted: Tue Sep 06, 2016 6:55 pm
Reply with quote

Hello all again,

Good News.. I believe I have done the Wildcard logic process in COBOL itself icon_biggrin.gif. Please find the code below. This should work according to below restrictions:
1. Wildcard Symbol * shouldn't occur continuously. 2. Wildcard symbols * and ? shouldn't occur contiuously.
You are much appreciated to correct me if you find something which can be done efficiently or logic holes any.
Code:
       FD  INPUT-FILE                                                   
           RECORDING MODE IS F BLOCK CONTAINS 0 RECORDS.                 
       01  IN-RECORD.                                                   
           05  WS-STRING             PIC X(20).                         
           05  FILLER                PIC X(30).                         
      *                                                                 
       WORKING-STORAGE SECTION.                                         
       01 WS-DATA.                                                       
           03  EOF                   PIC X(01) VALUE 'N'.               
      *        PARAMETER WITH / WITHOUT WILDCARD SYMBOLS '*' '?'         
      *    03  PARM                  PIC X(20) VALUE '*345'.             
      *    03  PARM                  PIC X(20) VALUE '*ES'.             
      *    03  PARM                  PIC X(20) VALUE '123*'.             
      *    03  PARM                  PIC X(20) VALUE 'PAY PAL*'.         
      *    03  PARM                  PIC X(20) VALUE '*AL SER*'.         
      *    03  PARM                  PIC X(20) VALUE 'E?AY?SE?'.         
           03  PARM                  PIC X(20) VALUE '*L SERV?C* LT?'.   
      *        CHARACTERS AFTER WILDCARD * IN PARAMETER                 
           03  PART1                 PIC X(20).                         
      *        CHARACTERS AFTER WILDCARD * BUT BEFORE ? IN PARAMETER     
           03  PART2                 PIC X(20).                         
      *        LENGTH OF PART1                                           
           03  WS-PART1              PIC 9(02) VALUE 0.                 
      *        LENGTH OF PART2                                           
           03  WS-PART2              PIC 9(02) VALUE 0.                 
      *        COUNT FOR WILDCARD '?'                                   
           03  WS-Q                  PIC 9(02) VALUE 0.                 
      *        COUNT FOR WILDCARD '*'                                   
           03  WS-A                  PIC 9(02) VALUE 0.                 
      *        STRING BYTE REFERENCE                                     
           03  WS-I                  PIC 9(02) VALUE 0.                 
      *        PARAMETER BYTE REFERENCE                                 
           03  WS-J                  PIC 9(02) VALUE 0.                 
      *        PARM LENGTH UNTIL NEXT WILDCARD                           
           03  WS-K                  PIC 9(02) VALUE 0.                 
      *        PARM LENGTH EXCL.TRAILING SPACES WHEN NO MORE WILDCARDS   
           03  WS-L                  PIC 9(02) VALUE 0.                 
      *        MATCHING PARM CHARS AFTER WILDCARD * AGAINST INPUT STRING
           03  WS-MATCH-FND          PIC X(01) VALUE ' '.               
               88 MATCH-FND                    VALUE 'Y'.               
      *        RESULT                                                   
           03  WS-COMPARE-FLAG       PIC X(01) VALUE ' '.               
               88 WS-COMPARE-TRUE              VALUE 'Y'.               
               88 WS-COMPARE-FALSE             VALUE 'N'.               
      *                                                               
       PROCEDURE DIVISION.                                           
      *                                                               
       0000-MAIN-CONTROL.                                             
           PERFORM 0100-MAIN-CONTROL                                 
           GOBACK                                                     
           .                                                         
      *                                                               
       0100-MAIN-CONTROL.                                             
           INSPECT PARM TALLYING WS-Q FOR ALL '?'                     
           INSPECT PARM TALLYING WS-A FOR ALL '*'                     
      *                                                               
           OPEN INPUT INPUT-FILE                                     
      *                                                               
           READ INPUT-FILE                                           
              AT END MOVE 'Y' TO EOF                                 
           END-READ                                                   
      *                                                               
           PERFORM UNTIL EOF = 'Y'                                   
              MOVE SPACE                 TO WS-COMPARE-FLAG           
              MOVE ZEROS                 TO WS-I                     
                                            WS-J                     
                                            WS-L                     
      *                                                                 
              EVALUATE TRUE ALSO TRUE                                   
                  WHEN WS-Q = 0        ALSO WS-A = 0                   
                       IF  PARM          IS EQUAL WS-STRING             
                           SET WS-COMPARE-TRUE  TO TRUE                 
                       ELSE                                             
                           SET WS-COMPARE-FALSE TO TRUE                 
                       END-IF                                           
                  WHEN OTHER                                           
                       PERFORM COMPLEX-LOGIC                           
                       IF NOT WS-COMPARE-TRUE  AND NOT WS-COMPARE-FALSE
                          SET WS-COMPARE-TRUE   TO TRUE                 
                       END-IF                                           
              END-EVALUATE                                             
      *                                                                 
              READ INPUT-FILE                                           
                 AT END MOVE 'Y' TO EOF                                 
                 NOT AT END                                             
                   IF WS-STRING IS EQUAL SPACES                         
                      MOVE 'Y' TO EOF                                   
                   END-IF                                               
              END-READ                                                 
           END-PERFORM                                                 
      *                                                                 
           CLOSE INPUT-FILE                                             
           .                                                           
      *                                                                 
       COMPLEX-LOGIC.                                                   
           MOVE 1                        TO WS-I                       
                                            WS-J                       
           PERFORM UNTIL WS-COMPARE-TRUE OR WS-COMPARE-FALSE    OR     
                           WS-I > LENGTH OF WS-STRING           OR     
                           WS-J > LENGTH OF WS-STRING                   
              EVALUATE TRUE                                             
                  WHEN PARM (WS-J:1)      = '?'                         
                       ADD 1             TO WS-I                       
                                            WS-J                     
                       SUBTRACT 1      FROM WS-Q                     
                  WHEN PARM (WS-J:1)      = WS-STRING (WS-I:1) AND   
                       PARM (WS-J:1)  NOT = '*'                     
                       ADD 1             TO WS-I                     
                                            WS-J                     
                  WHEN (PARM (WS-J:1) NOT = WS-STRING (WS-I:1) AND   
                        PARM (WS-J:1) NOT = '*')                     
                       SET WS-COMPARE-FALSE TO TRUE                 
                  WHEN PARM (WS-J:1)      = '*'                AND   
                       PARM (WS-J + 1:)   = SPACES                   
                       SET WS-COMPARE-TRUE  TO TRUE                 
                  WHEN OTHER                                         
                       ADD  1            TO WS-J                     
                       SUBTRACT 1      FROM WS-A                     
                       UNSTRING PARM(WS-J:) DELIMITED BY '*'         
                           INTO PART1 COUNT IN WS-PART1             
                       END-UNSTRING                                 
      *                                                             
                       IF  WS-A           = 0                       
                           INSPECT FUNCTION REVERSE(PART1)           
                                   TALLYING WS-L FOR LEADING SPACES 
                              COMPUTE WS-L = LENGTH OF PART1 - WS-L 
                              MOVE WS-L  TO WS-PART1                 
                       END-IF                                       
      *                                                             
                       IF  WS-Q           > 0                       
                           UNSTRING PART1   DELIMITED BY '?'         
                               INTO PART2 COUNT IN WS-PART2         
                           END-UNSTRING                             
                           MOVE WS-PART2 TO WS-PART1                 
                       END-IF                                       
      *                                                             
                       MOVE SPACE        TO WS-MATCH-FND             
                       COMPUTE WS-K       = LENGTH OF WS-STRING -   
                                            WS-PART1 + 1             
                       PERFORM UNTIL MATCH-FND  OR  WS-K < WS-I     
                           IF  WS-STRING(WS-K:WS-PART1) =           
                                      PART1(1:WS-PART1)             
                               SET MATCH-FND TO TRUE                 
                               COMPUTE WS-I = WS-K + WS-PART1       
                               COMPUTE WS-J = WS-J + WS-PART1       
                           ELSE                                     
                               SUBTRACT 1 FROM WS-K                 
                           END-IF                                   
                       END-PERFORM                                   
                       IF NOT MATCH-FND                             
                          SET WS-COMPARE-FALSE TO TRUE               
                       END-IF                                       
              END-EVALUATE                                           
           END-PERFORM                                               
           .                                                         
Back to top
View user's profile Send private message
enrico-sorichetti

Superior Member


Joined: 14 Mar 2007
Posts: 10888
Location: italy

PostPosted: Tue Sep 06, 2016 7:59 pm
Reply with quote

Quote:
1. Wildcard Symbol * shouldn't occur continuously.
2. Wildcard symbols * and ? shouldn't occur contiuously.


if ...
* stands for 0 or more chars
? stands for one char

a combination ?* is legal ... it requests for at last one char

anyway unless You want to be pedantic
if the pattern analysis is done properly
any mix of * and ? should work...
Back to top
View user's profile Send private message
Robert Sample

Global Moderator


Joined: 06 Jun 2008
Posts: 8700
Location: Dubuque, Iowa, USA

PostPosted: Tue Sep 06, 2016 8:33 pm
Reply with quote

Since your COMPLEX-LOGIC changes the values of WS-Q and WS-A, you need to place
Code:
           INSPECT PARM TALLYING WS-Q FOR ALL '?'                     
           INSPECT PARM TALLYING WS-A FOR ALL '*'
inside the PERFORM loop or you'll get invalid results for all input records after the first one.
Back to top
View user's profile Send private message
enrico-sorichetti

Superior Member


Joined: 14 Mar 2007
Posts: 10888
Location: italy

PostPosted: Tue Sep 06, 2016 9:08 pm
Reply with quote

I suggest to implement a simpler - MORE UNDERSTANDABLE - logic ...
in two weeks changing something in the current approach will be a nightmare
Back to top
View user's profile Send private message
dudenithy

New User


Joined: 02 Mar 2012
Posts: 48
Location: India

PostPosted: Tue Sep 06, 2016 9:15 pm
Reply with quote

Robert Sample wrote:
Since your COMPLEX-LOGIC changes the values of WS-Q and WS-A, you need to place
Code:
           INSPECT PARM TALLYING WS-Q FOR ALL '?'                     
           INSPECT PARM TALLYING WS-A FOR ALL '*'
inside the PERFORM loop or you'll get invalid results for all input records after the first one.


Agreed. Indeed I had INSPECT inside each file record read process during my testing. But when putting into forum, I simplified the code not to becoming too big icon_smile.gif.
Back to top
View user's profile Send private message
dudenithy

New User


Joined: 02 Mar 2012
Posts: 48
Location: India

PostPosted: Tue Sep 06, 2016 9:17 pm
Reply with quote

enrico-sorichetti wrote:
I suggest to implement a simpler - MORE UNDERSTANDABLE - logic ...
in two weeks changing something in the current approach will be a nightmare

I tried to be simplifier as much I can icon_mad.gif. Please be welcome if you could able to fine tune it icon_smile.gif.
Back to top
View user's profile Send private message
enrico-sorichetti

Superior Member


Joined: 14 Mar 2007
Posts: 10888
Location: italy

PostPosted: Tue Sep 06, 2016 9:17 pm
Reply with quote

Quote:
I simplified the code not to becoming too big


when You ask people to look at Your code,
You should post it completely, not just excerpts
Back to top
View user's profile Send private message
dudenithy

New User


Joined: 02 Mar 2012
Posts: 48
Location: India

PostPosted: Tue Sep 06, 2016 9:21 pm
Reply with quote

enrico-sorichetti wrote:
If ...
* stands for 0 or more chars
? stands for one char

a combination ?* is legal ... it requests for at last one char

anyway unless You want to be pedantic
if the pattern analysis is done properly
any mix of * and ? should work...

Yes, the rule is absolutely right and the Standard one.
Regarding combination ?*, my logic still works. combination *? will not work. My above mentioned restriction rule must be corrected. Thanks.
Back to top
View user's profile Send private message
dudenithy

New User


Joined: 02 Mar 2012
Posts: 48
Location: India

PostPosted: Tue Sep 06, 2016 9:26 pm
Reply with quote

enrico-sorichetti wrote:
when You ask people to look at Your code,
You should post it completely, not just excerpts

Yes Enrico, I should have.. lessons learnt icon_wink.gif.
Back to top
View user's profile Send private message
enrico-sorichetti

Superior Member


Joined: 14 Mar 2007
Posts: 10888
Location: italy

PostPosted: Wed Sep 07, 2016 2:24 am
Reply with quote

topic cleaned up of unsuitable solutions ...
a COBOL solution was requested.

for those who simply want to show alternative solutions in other languages
a new topic should be started with a tiltle along the lines of
'wildcard matching - REXX/C/BRAINFUCK/... whatever language ... solution'
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> COBOL Programming

 


Similar Topics
Topic Forum Replies
No new posts COBOL sorting, with input GDG base COBOL Programming 7
No new posts Need help with ADABAS query (COBOL-AD... All Other Mainframe Topics 0
No new posts Replacing FILLER with FILLER<SeqNu... DFSORT/ICETOOL 2
No new posts Compile Sp Cobol base COBOL Programming 1
No new posts SQLCODE=-311 in Cobol SP-DB2. COBOL Programming 2
Search our Forums:

Back to Top