Discussion:
How to do generic string matching
(too old to reply)
Bill Ashton
2016-06-15 14:09:41 UTC
Permalink
Raw Message
Hello again! I am working on a program, and am trying to find the best way
to perform some generic string matches.

A user will select a record based on three different fields, and I need to
use string matching for this. The data record is built earlier in the
program from multiple other records, but each selection field is a separate
word.

For example, the user could enter a selection mask of "**ST**EL*, and I
need to check every record for this mask in, for example, Word #1. The word
is always the same length, and there is only one selection mask.

My question is how to do this most efficiently.

I can do a loop of each character in the mask against the record, but since
I can have three different fields, this sounds like an overly intense
process to select or drop a record. Here is my code to do this:
*Do list# = 1 to list.0 *
*...If mask /= "********" Then *
*......Do loop# = 1 to Length(mask); *
*........._$ = Substr(mask,loop#,1) *
*.........If _$ /= "*" Then *
*............If _$ /= Substr(Word(list.list#,1),loop#,1) Then *
*...............Leave list#; /* Drop the record */*
*......End;*
*End;*

Is there a better way?

--
Thank you and best regards,
*Billy Ashton*

----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
send email to ***@VM.MARIST.EDU with the message: INFO TSO-REXX
Lizette Koehler
2016-06-15 14:25:21 UTC
Permalink
Raw Message
Bill,

I might look at including an ISPF EDIT Macro that can use PICTURE STRINGS or Regular Expressions. It might work better.

Lizette
-----Original Message-----
Bill Ashton
Sent: Wednesday, June 15, 2016 7:08 AM
Subject: [TSO-REXX] How to do generic string matching
Hello again! I am working on a program, and am trying to find the best way to
perform some generic string matches.
A user will select a record based on three different fields, and I need to use
string matching for this. The data record is built earlier in the program from
multiple other records, but each selection field is a separate word.
For example, the user could enter a selection mask of "**ST**EL*, and I need
to check every record for this mask in, for example, Word #1. The word is
always the same length, and there is only one selection mask.
My question is how to do this most efficiently.
I can do a loop of each character in the mask against the record, but since I
can have three different fields, this sounds like an overly intense process to
*Do list# = 1 to list.0 *
*...If mask /= "********" Then *
*......Do loop# = 1 to Length(mask); *
*........._$ = Substr(mask,loop#,1) *
*.........If _$ /= "*" Then *
*............If _$ /= Substr(Word(list.list#,1),loop#,1) Then *
*...............Leave list#; /* Drop the record */*
*......End;*
*End;*
Is there a better way?
--
Thank you and best regards,
*Billy Ashton*
----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
send email to ***@VM.MARIST.EDU with the message: INFO TSO-REXX
Bill Ashton
2016-06-15 14:33:39 UTC
Permalink
Raw Message
Hi Lizette, I thought of doing something like that, but since I am building
the records in the program, it seems like a lot of overhead to then write
the stem set to a file and then to edit that file using an edit macro. I am
hoping to do it all inside the program without any special processing like
ISPF services.

Billy
Post by Lizette Koehler
Bill,
I might look at including an ISPF EDIT Macro that can use PICTURE STRINGS
or Regular Expressions. It might work better.
Lizette
-----Original Message-----
Behalf Of
Bill Ashton
Sent: Wednesday, June 15, 2016 7:08 AM
Subject: [TSO-REXX] How to do generic string matching
Hello again! I am working on a program, and am trying to find the best
way to
perform some generic string matches.
A user will select a record based on three different fields, and I need
to use
string matching for this. The data record is built earlier in the
program from
multiple other records, but each selection field is a separate word.
For example, the user could enter a selection mask of "**ST**EL*, and I
need
to check every record for this mask in, for example, Word #1. The word is
always the same length, and there is only one selection mask.
My question is how to do this most efficiently.
I can do a loop of each character in the mask against the record, but
since I
can have three different fields, this sounds like an overly intense
process to
*Do list# = 1 to list.0 *
*...If mask /= "********" Then *
*......Do loop# = 1 to Length(mask); *
*........._$ = Substr(mask,loop#,1) *
*.........If _$ /= "*" Then *
*............If _$ /= Substr(Word(list.list#,1),loop#,1) Then *
*...............Leave list#; /* Drop the record */*
*......End;*
*End;*
Is there a better way?
--
Thank you and best regards,
*Billy Ashton*
----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
--
Thank you and best regards,
*Billy Ashton*

----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
send email to ***@VM.MARIST.EDU with the message: INFO TSO-REXX
Lizette Koehler
2016-06-15 14:56:02 UTC
Permalink
Raw Message
You might also look at Mark Zelden's website (as other who have written REXX code) and see if anything looks helpful.
http://www.mzelden.com/mvsutil.html

Lizette
-----Original Message-----
Bill Ashton
Sent: Wednesday, June 15, 2016 7:34 AM
Subject: Re: [TSO-REXX] How to do generic string matching
Hi Lizette, I thought of doing something like that, but since I am building
the records in the program, it seems like a lot of overhead to then write the
stem set to a file and then to edit that file using an edit macro. I am hoping
to do it all inside the program without any special processing like ISPF
services.
Billy
Post by Lizette Koehler
Bill,
I might look at including an ISPF EDIT Macro that can use PICTURE
STRINGS or Regular Expressions. It might work better.
Lizette
-----Original Message-----
Behalf Of
Bill Ashton
Sent: Wednesday, June 15, 2016 7:08 AM
Subject: [TSO-REXX] How to do generic string matching
Hello again! I am working on a program, and am trying to find the best
way to
perform some generic string matches.
A user will select a record based on three different fields, and I need
to use
string matching for this. The data record is built earlier in the
program from
multiple other records, but each selection field is a separate word.
For example, the user could enter a selection mask of "**ST**EL*, and I
need
to check every record for this mask in, for example, Word #1. The
word is always the same length, and there is only one selection mask.
My question is how to do this most efficiently.
I can do a loop of each character in the mask against the record, but
since I
can have three different fields, this sounds like an overly intense
process to
*Do list# = 1 to list.0 *
*...If mask /= "********" Then *
*......Do loop# = 1 to Length(mask); *
*........._$ = Substr(mask,loop#,1) *
*.........If _$ /= "*" Then *
*............If _$ /= Substr(Word(list.list#,1),loop#,1) Then *
*...............Leave list#; /* Drop the record */*
*......End;*
*End;*
Is there a better way?
--
Thank you and best regards,
*Billy Ashton*
----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
send email to ***@VM.MARIST.EDU with the message: INFO TSO-REXX
John McKown
2016-06-15 14:58:36 UTC
Permalink
Raw Message
Post by Bill Ashton
Hi Lizette, I thought of doing something like that, but since I am building
the records in the program, it seems like a lot of overhead to then write
the stem set to a file and then to edit that file using an edit macro. I am
hoping to do it all inside the program without any special processing like
ISPF services.
Billy
​OK, this is definitely an "off the wall" idea. First off, I assume that
the * matches exactly one character, no more, no less. If it can match
anything else, then this won't work. Suppose your mask is in the variable
MASK and the string to search is in STRING. You might do something like
this:

NULL=X'00' /* HEX ZERO CHARACTER - AKA LOW-VALUES */
NEWMASK=TRANSLATE(MASK,NULL,'*') /* TRANSLATE ASTERISK TO LOW-VALUES */
IF LENGTH(MASK) > LENGTH(STRING) THEN SIGNAL CANTMATCH
MATCHED=0
DO OFFSET=1 TO LENGTH(STRING)-LENGTH(MASK) UNTIL MATCHED = 1
TESTVAL=BITAND(SUBSTR(STRING,OFFSET,LENGTH(MASK)),NEWMASK)
IF TESTVAL = NEWMASK THEN MATCHED = 1
END
IF MATCHED = 1 THEN SIGNAL MATCHED

The "magic" is the BITAND. When you BITAND a value with binary zero, you
get binary zero. That's why you change the asterisk in the mask to
LOW-VALUES, to force the wildcard positions in the string to be tested to
x'00'. Also, when you BITAND a value with (and only with) an equal value,
you get your original value back. So the end result of the BITAND will be
equal to the NEWMASK value if and only if the non-wildcard positions in the
string are equal to the non-wildcard positions in the MASK.

NOT TESTED!
--
"Pessimism is a admirable quality in an engineer. Pessimistic people check
their work three times, because they're sure that something won't be right.
Optimistic people check once, trust in Solis-de to keep the ship safe, then
blow everyone up."
"I think you're mistaking the word optimistic for inept."
"They've got a similar ring to my ear."

From "Star Nomad" by Lindsay Buroker:

Maranatha! <><
John McKown

----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
send email to ***@VM.MARIST.EDU with the message: INFO TSO-REXX
John McKown
2016-06-15 15:02:06 UTC
Permalink
Raw Message
Post by John McKown
Post by Bill Ashton
Hi Lizette, I thought of doing something like that, but since I am building
the records in the program, it seems like a lot of overhead to then write
the stem set to a file and then to edit that file using an edit macro. I am
hoping to do it all inside the program without any special processing like
ISPF services.
Billy
​OK, this is definitely an "off the wall" idea. First off, I assume that
the * matches exactly one character, no more, no less. If it can match
anything else, then this won't work. Suppose your mask is in the variable
MASK and the string to search is in STRING. You might do something like
NULL=X'00' /* HEX ZERO CHARACTER - AKA LOW-VALUES */
NEWMASK=TRANSLATE(MASK,NULL,'*') /* TRANSLATE ASTERISK TO LOW-VALUES */
IF LENGTH(MASK) > LENGTH(STRING) THEN SIGNAL CANTMATCH
MATCHED=0
DO OFFSET=1 TO LENGTH(STRING)-LENGTH(MASK) UNTIL MATCHED = 1
​off-by one error above s/b TO LENGTH(STRING)-LENGTH(MASK)+1​
Post by John McKown
TESTVAL=BITAND(SUBSTR(STRING,OFFSET,LENGTH(MASK)),NEWMASK)
IF TESTVAL = NEWMASK THEN MATCHED = 1
END
IF MATCHED = 1 THEN SIGNAL MATCHED
The "magic" is the BITAND. When you BITAND a value with binary zero, you
get binary zero. That's why you change the asterisk in the mask to
LOW-VALUES, to force the wildcard positions in the string to be tested to
x'00'. Also, when you BITAND a value with (and only with) an equal value,
you get your original value back. So the end result of the BITAND will be
equal to the NEWMASK value if and only if the non-wildcard positions in the
string are equal to the non-wildcard positions in the MASK.
NOT TESTED!
--
"Pessimism is a admirable quality in an engineer. Pessimistic people check
their work three times, because they're sure that something won't be right.
Optimistic people check once, trust in Solis-de to keep the ship safe, then
blow everyone up."
"I think you're mistaking the word optimistic for inept."
"They've got a similar ring to my ear."
Maranatha! <><
John McKown
--
"Pessimism is a admirable quality in an engineer. Pessimistic people check
their work three times, because they're sure that something won't be right.
Optimistic people check once, trust in Solis-de to keep the ship safe, then
blow everyone up."
"I think you're mistaking the word optimistic for inept."
"They've got a similar ring to my ear."

From "Star Nomad" by Lindsay Buroker:

Maranatha! <><
John McKown

----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
send email to ***@VM.MARIST.EDU with the message: INFO TSO-REXX
Bill Ashton
2016-06-15 16:38:41 UTC
Permalink
Raw Message
John, this sounded like a brilliant idea and just like the kinds of things
I think of!

I did run into something, though that failed the test, and I am not sure
how to get around it. Here is the scenario:
Mask = "***BC*****"
String = "FLOBC16102" -> This works and passes the test.
String = "FLOCC16104" -> This also passes the test.

It seems that the mask winds up with x'00 00 00 C2 C3 ...' after the
translation, and obviously when the string is equal - in the first case -
it will work. Then, in the second case, the AND of CC and BC results in BC
(Bitand ('C2C3'x,'C3C3'x) = 'C2C3'x), resulting in this mismatch being
selected.

Do you have any idea how to tweak this to be right?

Billy
Post by John McKown
Post by John McKown
Post by Bill Ashton
Hi Lizette, I thought of doing something like that, but since I am building
the records in the program, it seems like a lot of overhead to then
write
Post by John McKown
Post by Bill Ashton
the stem set to a file and then to edit that file using an edit macro. I am
hoping to do it all inside the program without any special processing
like
Post by John McKown
Post by Bill Ashton
ISPF services.
Billy
​OK, this is definitely an "off the wall" idea. First off, I assume that
the * matches exactly one character, no more, no less. If it can match
anything else, then this won't work. Suppose your mask is in the variable
MASK and the string to search is in STRING. You might do something like
NULL=X'00' /* HEX ZERO CHARACTER - AKA LOW-VALUES */
NEWMASK=TRANSLATE(MASK,NULL,'*') /* TRANSLATE ASTERISK TO LOW-VALUES */
IF LENGTH(MASK) > LENGTH(STRING) THEN SIGNAL CANTMATCH
MATCHED=0
DO OFFSET=1 TO LENGTH(STRING)-LENGTH(MASK) UNTIL MATCHED = 1
​off-by one error above s/b TO LENGTH(STRING)-LENGTH(MASK)+1​
Post by John McKown
TESTVAL=BITAND(SUBSTR(STRING,OFFSET,LENGTH(MASK)),NEWMASK)
IF TESTVAL = NEWMASK THEN MATCHED = 1
END
IF MATCHED = 1 THEN SIGNAL MATCHED
The "magic" is the BITAND. When you BITAND a value with binary zero, you
get binary zero. That's why you change the asterisk in the mask to
LOW-VALUES, to force the wildcard positions in the string to be tested to
x'00'. Also, when you BITAND a value with (and only with) an equal value,
you get your original value back. So the end result of the BITAND will be
equal to the NEWMASK value if and only if the non-wildcard positions in
the
Post by John McKown
string are equal to the non-wildcard positions in the MASK.
NOT TESTED!
--
"Pessimism is a admirable quality in an engineer. Pessimistic people
check
Post by John McKown
their work three times, because they're sure that something won't be
right.
Post by John McKown
Optimistic people check once, trust in Solis-de to keep the ship safe,
then
Post by John McKown
blow everyone up."
"I think you're mistaking the word optimistic for inept."
"They've got a similar ring to my ear."
Maranatha! <><
John McKown
--
"Pessimism is a admirable quality in an engineer. Pessimistic people check
their work three times, because they're sure that something won't be right.
Optimistic people check once, trust in Solis-de to keep the ship safe, then
blow everyone up."
"I think you're mistaking the word optimistic for inept."
"They've got a similar ring to my ear."
Maranatha! <><
John McKown
----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
--
Thank you and best regards,
*Billy Ashton*

----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
send email to ***@VM.MARIST.EDU with the message: INFO TSO-REXX
John McKown
2016-06-15 17:52:25 UTC
Permalink
Raw Message
Post by Bill Ashton
John, this sounded like a brilliant idea and just like the kinds of things
I think of!
I did run into something, though that failed the test, and I am not sure
Mask = "***BC*****"
String = "FLOBC16102" -> This works and passes the test.
String = "FLOCC16104" -> This also passes the test.
It seems that the mask winds up with x'00 00 00 C2 C3 ...' after the
translation, and obviously when the string is equal - in the first case -
it will work. Then, in the second case, the AND of CC and BC results in BC
(Bitand ('C2C3'x,'C3C3'x) = 'C2C3'x), resulting in this mismatch being
selected.
Do you have any idea how to tweak this to be right?
Billy
​I now have two things. A solution (I think) and a headache. Try this:

​/*REXX*/
MASK = "***BC*****"
STRING = "FLOBC16102"
CALL DOMATCH MASK,STRING
STRING = "FLOCC16104"
CALL DOMATCH MASK,STRING
RETURN
DOMATCH: PROCEDURE
PARSE ARG MASK,STRING
NULL='00'X /* HEX ZERO CHARACTER - AKA LOW-VALUES */
NEWMASK1=TRANSLATE(MASK,NULL,'*')
/* TRANSLATE ASTERISK TO LOW-VALUES */
NEWMASK2=TRANSLATE(MASK,'FF'X,'*')
/* TRANSLATE ASTERISK TO HIGH-VALUES */
NEWMASK3=LEFT('FF'X,LENGTH(MASK),'FF'X)
/* A STRING OF X'FF' AS LONG AS THE MASK */
NEWMASK4=BITXOR(NEWMASK2,NEWMASK3)
NEWMASK4=TRANSLATE(NEWMASK4,'00'X,'FF'X)
NEWMASK5=BITXOR(NEWMASK1,NEWMASK4)
/* A STRING WITH X'00' WHERE THERE WERE * AND X'FF' ELSEWHERE */
IF LENGTH(MASK) > LENGTH(STRING) THEN SIGNAL CANTMATCH
MATCHED=0
DO OFFSET=1 TO LENGTH(STRING)-LENGTH(MASK)+1 UNTIL MATCHED = 1
TESTVAL=BITAND(SUBSTR(STRING,OFFSET,LENGTH(MASK)),NEWMASK5)
IF TESTVAL = NEWMASK1 THEN MATCHED = 1
END
SAY MATCHED OFFSET
RETURN OFFSET * MATCHED
CANTMATCH:
RETURN -1

The masks are what gave me the headache. NEWMASK1 is the MASK value with
all asterisks replaced by x'00' with other values unchanged. ​NEWMASK2 is
the MASK value with all asterisks replaced by x'ff'. NEWMASK3 is a string
the same length as MASK made up of all x'ff' (for bit inversion using
BITXOR). NEWMASK4 is MASK with asterisks replaced by x'00' and all other
characters being bit inverted (b'0'<->b'1'). NEWMASK5 is the MASK value
where the asterisks are replaced by x'00' and everything else by x'ff'. The
BITAND takes the part of the string which we are test (selected by the
SUBSTR() ) and makes the postions where the MASK has a '*' become x'00' or
leaves it alone entirely (because the NEWMASK5 value is x'ff' in those
character positions). It then tests against the NEWMASK1 value and if
equal, there is a match. Whew. Even trying to explain it make my head hurt.

This code definitely is not nice or easily comprehended by the "average"
programmer (IMO). Therefore, many would regard it as "unmaintainable". Of
course, "maintainable" in today's world mean "can be understood by the
average Windows coder". But I'm getting nasty, I guess.
--
"Pessimism is a admirable quality in an engineer. Pessimistic people check
their work three times, because they're sure that something won't be right.
Optimistic people check once, trust in Solis-de to keep the ship safe, then
blow everyone up."
"I think you're mistaking the word optimistic for inept."
"They've got a similar ring to my ear."

From "Star Nomad" by Lindsay Buroker:

Maranatha! <><
John McKown

----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
send email to ***@VM.MARIST.EDU with the message: INFO TSO-REXX
Noack, Steve
2016-06-15 14:47:53 UTC
Permalink
Raw Message
Bill, I got this from somewhere in 2007. I don't remember if it was posted here, if I pulled it from a CBT tape or found it on a REXX related website. Maybe you can use it as-is or get ideas from it. I won't make any claims that it is better or worse than what you are already doing. It is a function that returns a 1 if there is a match and zero if not. Author and use are documented in the comments.



/* Matchmsk rexx */
/* ------------------------------------------------------------------ */
/* function: Match function in REXX */
/* */
/* call: result = matchmsk( spec, name ) */
/* */
/* where: spec - mask (containing % and * as joker) */
/* name - test string */
/* */
/* returns: 1 - name matches spec */
/* 0 - name does not match spec */
/* */
/* History: */
/* C-Version D.Ahlgrimm 03.1995 */
/* (see EMail Addresses) */
/* REXX-Version D.Ahlgrimm 21.06.1995 */
/* */
/* 05.09.1996 D.Ahlgrimm */
/* REXX-Code & Algorithmus optimiert */
/* (u.a. Grenzen genauer) */
/* */
/* 16.11.1996 Translated comments into english */
/* and reformatted the code /bs */
/* */
/* ------------------------------------------------------------------ */
PARSE ARG spec, name

spec_lng = LENGTH( spec )+1
name_lng = LENGTH( name )+1
spec_pos = 1
name_pos = 1

/* do for all chars in spec */
DO WHILE spec_pos<spec_lng

spec_ptr = SUBSTR( spec, spec_pos, 1 )
name_ptr = SUBSTR( name, name_pos, 1 )

IF spec_ptr = "*" THEN
DO
IF spec_pos+1 = spec_lng THEN
/* spec equal '*' -> finished, rest meaningless */
RETURN( 1 )

ss = SUBSTR( spec, spec_pos+1 )

/* as: Number of '*' in spec */
as = LENGTH( SPACE( TRANSLATE( ss, COPIES( " ", C2D( "*" ) )"x",,
" " ), 0 ) )

DO i = 0 to name_lng-name_pos-( LENGTH( ss )-as )

/* 0 to length - current position - count ... */
/* ...of the chars not equal '*' in spec */

IF Matchmsk( ss, SUBSTR( name, name_pos+i ) ) = 1 THEN
/* the rest of spec (after the *) matches */
/* the rest of name */
RETURN( 1 )

END /* DO i = 0 to name_lng-name_pos-( LENGTH( ss )-as ) */

/* no match for the rest found */
RETURN( 0 )
END; /* IF spec_ptr = "*" THEN */
ELSE
DO
IF ( spec_ptr = "%" & name_pos<>name_lng ) |,
spec_ptr = name_ptr THEN
DO
spec_pos = spec_pos+1
name_pos = name_pos+1
END /* IF ( spec_ptr = "%" & ... ) */
ELSE
/* spec equal '%' and the name is done .. */
/* ... or character is okay */
RETURN( 0 )
END /* ELSE */
END /* DO WHILE spec_pos<spec_lng */

IF name_pos <> name_lng THEN
/* spec is done, name is not */
RETURN( 0 )
/* spec and name are both done */
RETURN( 1 )




Thanks,
Steve Noack

-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-***@VM.MARIST.EDU] On Behalf Of Bill Ashton
Sent: Wednesday, June 15, 2016 9:34 AM
To: TSO-***@VM.MARIST.EDU
Subject: Re: How to do generic string matching

Hi Lizette, I thought of doing something like that, but since I am building the records in the program, it seems like a lot of overhead to then write the stem set to a file and then to edit that file using an edit macro. I am hoping to do it all inside the program without any special processing like ISPF services.

Billy
Post by Lizette Koehler
Bill,
I might look at including an ISPF EDIT Macro that can use PICTURE
STRINGS or Regular Expressions. It might work better.
Lizette
-----Original Message-----
Behalf Of
Bill Ashton
Sent: Wednesday, June 15, 2016 7:08 AM
Subject: [TSO-REXX] How to do generic string matching
Hello again! I am working on a program, and am trying to find the
best
way to
perform some generic string matches.
A user will select a record based on three different fields, and I
need
to use
string matching for this. The data record is built earlier in the
program from
multiple other records, but each selection field is a separate word.
For example, the user could enter a selection mask of "**ST**EL*,
and I
need
to check every record for this mask in, for example, Word #1. The
word is always the same length, and there is only one selection mask.
My question is how to do this most efficiently.
I can do a loop of each character in the mask against the record,
but
since I
can have three different fields, this sounds like an overly intense
process to
*Do list# = 1 to list.0 *
*...If mask /= "********" Then *
*......Do loop# = 1 to Length(mask); *
*........._$ = Substr(mask,loop#,1) *
*.........If _$ /= "*" Then *
*............If _$ /= Substr(Word(list.list#,1),loop#,1) Then *
*...............Leave list#; /* Drop the record */*
*......End;*
*End;*
Is there a better way?
--
Thank you and best regards,
*Billy Ashton*
----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions, send
--
Thank you and best regards,
*Billy Ashton*

----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions, send email to ***@VM.MARIST.EDU with the message: INFO TSO-REXX
-----Message Disclaimer-----

This e-mail message is intended only for the use of the individual or entity to which it is addressed, and may contain information that is privileged, confidential and exempt from disclosure under applicable law. If you are not the intended recipient, any dissemination, distribution or copying of this communication is strictly prohibited. If you have received this communication in error, please notify us immediately by reply email to ***@principal.com and delete or destroy all copies of the original message and attachments thereto. Email sent to or from the Principal Financial Group or any of its member companies may be retained as required by law or regulation.

Nothing in this message is intended to constitute an Electronic signature for purposes of the Uniform Electronic Transactions Act (UETA) or the Electronic Signatures in Global and National Commerce Act ("E-Sign") unless a specific statement to the contrary is included in this message.

If you no longer wish to receive any further solicitation from the Principal Financial Group you may unsubscribe at https://www.principal.com/do-not-contact-form any time.

If you are a Canadian resident and no longer wish to receive commercial electronic messages you may unsubscribe at https://www.principal.com/do-not-email-request-canadian-residents any time.
Ze'ev Atlas
2016-06-15 17:09:45 UTC
Permalink
Raw Message
Call the posix regex functions that should be available to you on z/os in one of the cee libraries
Regcomp, regexec, regerror, regfree
Or you may download the PCRE2 package (file 939 on cbttape.org) and figure out how to call it from Rexx
Za
Sent from Yahoo Mail on Android

On Wed, Jun 15, 2016 at 10:07 AM, Bill Ashton<***@GMAIL.COM> wrote: Hello again! I am working on a program, and am trying to find the best way
to perform some generic string matches.

A user will select a record based on three different fields, and I need to
use string matching for this. The data record is built earlier in the
program from multiple other records, but each selection field is a separate
word.

For example, the user could enter a selection mask of "**ST**EL*, and I
need to check every record for this mask in, for example, Word #1. The word
is always the same length, and there is only one selection mask.

My question is how to do this most efficiently.

I can do a loop of each character in the mask against the record, but since
I can have three different fields, this sounds like an overly intense
process to select or drop a record. Here is my code to do this:
*Do list# =  1 to list.0 *
*...If mask /= "********" Then  *
*......Do loop# = 1 to Length(mask);                  *
*........._$ = Substr(mask,loop#,1)                          *
*.........If _$ /= "*" Then                                  *
*............If _$ /= Substr(Word(list.list#,1),loop#,1) Then *
*...............Leave list#;    /* Drop the record */*
*......End;*
*End;*

Is there a better way?

--
Thank you and best regards,
*Billy Ashton*

----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
send email to ***@VM.MARIST.EDU with the message: INFO TSO-REXX


----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
send email to ***@VM.MARIST.EDU with the message: INFO TSO-REXX
Loading...