# examine for pattern

**URL:** <https://techcommunity.softwareag.com/t/examine-for-pattern/61387>\
**Category:** Forum\
**Tags:** Adabas-Natural, Natural, Natural-on-Mainframes\
**Created:** [September 7, 2006, 2:33am UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387 "2006-09-07T02:33:04Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![Joseph](https://avatars.discourse-cdn.com/v4/letter/j/dc4da7/32.png) [@Joseph](https://techcommunity.softwareag.com/u/Joseph)\
**Post date:** [September 7, 2006, 2:33am UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387/1 "2006-09-07T02:33:04Z")

</div>

Hello,  
I was wondering whether when using an EXAMINE FOR PATTERN statement, it is possible:

1. To specify wildcards that represent numbers
2. When a pattern was found in my string, to get the substring that matched the pattern, or to get the length of the pattern-matching substring.

Thanks a lot,  
Joseph

---

<div class="post-metadata">

**Author:** ![Weihnachtsbar](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/weihnachtsbar/32/146_2.png) [@Weihnachtsbar](https://techcommunity.softwareag.com/u/Weihnachtsbar)\
**Post date:** [September 7, 2006, 7:44pm UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387/2 "2006-09-07T19:44:18Z")

</div>

1. NO as far as I know → documentation says:  
A period (.), question mark (?) or underscore (\_) indicates a single position that is not to be examined.  
An asterisk (\*) or a percent sign (%) indicates any number of positions not to be examined.

2. NO as far as I know - you have to programm it your self…

```auto
DEFINE DATA LOCAL
1 #LENGTH (I4)
1 #AFTERREPLACE (I4)
1 #PATTERNLENGTH (I4)
1 #PATTERNSTART (I4)
*
1 #ORIGINAL (A250)
1 #COPY (A250)
1 #FOUNDPATTERN (A250)
1 #FINDPATTERN (A250)
END-DEFINE
*
#ORIGINAL := 'When a pattern was found in my string, to get the '-
  ' substring that matched the pattern, or to get the length of the'-
  ' pattern-matching substring'
*
#FINDPATTERN := 'a*the'
*
EXAMINE #ORIGINAL FOR ' ' GIVING LENGTH #LENGTH
#COPY := #ORIGINAL
EXAMINE #COPY FOR PATTERN #FINDPATTERN REPLACE FIRST WITH '.'
GIVING LENGTH #AFTERREPLACE
*
IF #LENGTH NE #AFTERREPLACE
  #PATTERNLENGTH := #LENGTH - #AFTERREPLACE + 1
  EXAMINE #ORIGINAL FOR PATTERN #FINDPATTERN
  GIVING POSITION #PATTERNSTART
*
  #FOUNDPATTERN := SUBSTR(#ORIGINAL, #PATTERNSTART, #PATTERNLENGTH)
ELSE
  WRITE 'Error: pattern not found'
END-IF
*
PRINT "=" #FOUNDPATTERN
*
END
```

---

<div class="post-metadata">

**Author:** ![Steve\_Robinson](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/steve_robinson/32/107_2.png) [@Steve\_Robinson](https://techcommunity.softwareag.com/u/Steve_Robinson)\
**Post date:** [September 8, 2006, 7:50pm UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387/3 "2006-09-08T19:50:02Z")

</div>

Starting with the next issue of Inside Natural (see website; address below in signature)  
I have added a new column. It is called “CPU Police”. The premise of the column  
is simple. Many programmers, usually under time constraints, write code for simple  
functions without considering alternative code. The code ends up in production.  
Unfortunately, sometimes this code ends up within loops that are executed literally  
millions of times per day.

Take the code that Weihnachsbar contributed to address the posting of Joseph regarding  
“extracting” a “pattern” text string. My guess is that virtually everyone reading this  
would implement this solution without giving it a second thought. It is a fine solution,  
except, one can write code that performs the same function yet executes in one third  
the time (and consumes about half the CPU time).

This is NOT to discourage participation in this forum (or, SAG-L for that matter).  
To the contrary, the point of this posting is to encourage individuals within  
the Natural community to find ways to better utilize Natural by writing more efficient code,  
AND, sharing that code with the rest of the user community.

Part of the problem is that when the original posting was made it sort of specified  
“PATTERN” as part of the solution. As will be shown below, “extracting” a “pattern”  
of characters is not something that the PATTERN option does very well. Knowing that  
PATTERN is fairly expensive, and noting that the posted solution had two EXAMINE for  
PATTERNs, I rewrote a solution as follows:

EXAMINE #ORIGINAL FOR ‘a’ GIVING POSITION #PATTERNSTART  
EXAMINE SUBSTRING (#ORIGINAL,#PATTERNSTART) FOR ‘the’  
GIVING POSITION #LENGTH  
ADD 2 TO #LENGTH /\* AFTER EXAMINE, ONLY HAVE UPTO THE t

Note, I have, for demonstration simplicity, eliminated various tests, and the  
final MOVE SUBSTRING, which would be in common with the original solution.

The point of the above is that two EXAMINEs without PATTERN were likely to be  
faster than two EXAMINEs with PATTERN, plus an EXAMINE without PATTERN, plus  
a MOVE.

I wrote a timing comparison on my PC (Natural 6.1.1). Here is the code and the  
output.

DEFINE DATA LOCAL  
1 #LENGTH (I4)  
1 #AFTERREPLACE (I4)  
1 #PATTERNLENGTH (I4)  
1 #PATTERNSTART (I4)  
\*  
1 #ORIGINAL (A250)  
1 #COPY (A250)  
1 #FOUNDPATTERN (A250)  
1 #FINDPATTERN (A250)  
1 #LOOP (P9)  
1 #START-CPU (P9)  
1 #CPU-ELAPSED (P9)  
END-DEFINE  
\*  
INCLUDE AATITLER  
INCLUDE AASETC  
\*  
#ORIGINAL := ‘When a pattern was found in my string, to get the ‘-  
’ substring that matched the pattern, or to get the length of the’-  
’ pattern-matching substring’  
\*  
#FINDPATTERN := ‘a\*the’  
\*  
SETB. SETTIME  
MOVE _CPU-TIME TO #START-CPU  
FOR #LOOP = 1 TO 100000  
EXAMINE #ORIGINAL FOR ‘a’ GIVING POSITION #PATTERNSTART  
EXAMINE SUBSTRING (#ORIGINAL,#PATTERNSTART) FOR ‘the’  
GIVING POSITION #LENGTH  
ADD 2 TO #LENGTH /_ AFTER EXAMINE, ONLY HAVE UPTO THE t  
END-FOR  
COMPUTE #CPU-ELAPSED = \*CPU-TIME - #START-CPU  
WRITE 5T ‘FAST WAY’ \*TIMD (SETB.) #CPU-ELAPSED /  
\*  
SETA. SETTIME  
MOVE \*CPU-TIME TO #START-CPU  
FOR #LOOP = 1 TO 100000  
EXAMINE #ORIGINAL FOR ’ ’ GIVING LENGTH #LENGTH  
#COPY := #ORIGINAL  
EXAMINE #COPY FOR PATTERN #FINDPATTERN REPLACE FIRST WITH ‘.’  
GIVING LENGTH #AFTERREPLACE  
\*  
#PATTERNLENGTH := #LENGTH - #AFTERREPLACE + 1  
EXAMINE #ORIGINAL FOR PATTERN #FINDPATTERN  
GIVING POSITION #PATTERNSTART  
END-FOR  
COMPUTE #CPU-ELAPSED = \*CPU-TIME - #START-CPU  
WRITE 5T ‘SLOW WAY’ \*TIMD (SETA.) #CPU-ELAPSED /  
\*  
SETC. SETTIME  
MOVE \*CPU-TIME TO #START-CPU  
FOR #LOOP = 1 TO 100000  
IGNORE  
END-FOR  
COMPUTE #CPU-ELAPSED = \*CPU-TIME - #START-CPU  
WRITE 5T ‘FOR LOOP’ \*TIMD (SETC.) #CPU-ELAPSED  
END

```
PAGE # 1 DATE: Sep 08, 2006
PROGRAM: PATTRN04 LIBRARY: SYSTEM

FAST WAY 33 324

SLOW WAY 48 466

FOR LOOP 5 56

```

For a meaningful comparison, one has to subtract the overhead of the FOR loop from the  
two approaches. Thus, the elapsed times are 28 versus 43 ( a saving of a third in the  
elapsed time ) and the CPU times are 268 versus 410 (a similar saving of about a third).

Then I realized that I could improve Weihnachsbar’s code. The second EXAMINE for PATTERN  
was actually not necessary. Instead, the functionality of the second EXAMINE for PATTERN  
could be incorporated within the first EXAMINE for PATTERN, as in:

```
EXAMINE #COPY FOR PATTERN #FINDPATTERN REPLACE FIRST WITH '.'
            GIVING POSITION #PATTERNSTART GIVING LENGTH #AFTERREPLACE

```

The new timings were:

```
PAGE # 1 DATE: Sep 08, 2006
PROGRAM: PATTRN05 LIBRARY: SYSTEM

FAST WAY 33 324

SLOW WAY 36 349

FOR LOOP 5 56

```

The difference between the two was certainly reduced. After FOR loop subtractions, the  
performance difference was down to about 10% (as opposed to 30% earlier).

Then I remembered an interesting fact. SUBSTRING on the mainframe was rewritten  
for Version 4, resulting in substantial performance improvement. I ran PATTRN05  
on the mainframe. Here are the numbers:

```
PAGE # 1 DATE: Sep 08, 2006
PROGRAM: PATTRN05 LIBRARY: SYSTEM

FAST WAY 4 37

SLOW WAY 11 64

FOR LOOP 1 5

```

Since most of you, I am sure, run Natural on the mainframe, the numbers above  
are the most important in this exercise. Subtracting out the FOR loop, shows an  
almost 50 reduction in CPU time, and a 2/3 reduction in elapsed time.

steve

---

<div class="post-metadata">

**Author:** ![Ralph\_Zbrog](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/ralph_zbrog/32/78_2.png) [@Ralph\_Zbrog](https://techcommunity.softwareag.com/u/Ralph_Zbrog)\
**Post date:** [September 9, 2006, 2:26am UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387/4 "2006-09-09T02:26:37Z")

</div>

I agree wholeheartedly that reduction of CPU is an important goal. My Natural and Adabas training classes focus on this. My corporate motto is “Faster code. Faster.” That is, the least amount of code to do the job in the least amount of time.

That said, I disagree that the “fast way” posted above can be considered a reasonable alternative to the “slow way.” It’s faster because it has less functionality.

Weihnachtsbar’s code is (almost) a real-life example, and satisfies the requirement of a pattern-searching algorithm. Try it with a pattern of “tt_s f_y”. The “improved” code works only for a single example. The introduction of multiple wildcards affects the code and the CPU comparison.

Perhaps the “CPU reduction” posting belongs in a separate thread, with practical examples.

---

<div class="post-metadata">

**Author:** ![Steve\_Robinson](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/steve_robinson/32/107_2.png) [@Steve\_Robinson](https://techcommunity.softwareag.com/u/Steve_Robinson)\
**Post date:** [September 10, 2006, 3:25am UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387/5 "2006-09-10T03:25:24Z")

</div>

[color=“blue”]Ralph Zbrog wrote:

That said, I disagree that the “fast way” posted above can be considered  
a reasonable alternative to the “slow way.” It’s faster because  
it has less functionality.[/color]

The “slow” way was written by Weihnachtsbar in response to a specific  
requirement as stated in the original posting by Joseph. The “fast” way code  
was also offered as a response to the original request, not as a  
general pattern-searching algorithm. If one restricts one’s perspective  
to the requested functionality, then the two pieces of code have equivalent  
functionality.

Try it with a pattern of “tt_sf_y”. The “improved” code works only  
for a single example. The introduction of multiple wildcards affects  
the code and the CPU comparison.

How about a pattern of ‘a_rn_st’ (which is germane to the posted query’s data)

Indeed, the code has to be re-written, as shown below:

EXAMINE #ORIGINAL FOR ‘a’ GIVING POSITION #PATTERNSTART  
EXAMINE SUBSTRING (#ORIGINAL,#PATTERNSTART) FOR ‘rn’  
GIVING POSITION #LENGTH1  
ADD #PATTERNSTART to #LENGTH1  
\*  
EXAMINE SUBSTRING (#ORIGINAL,#LENGTH1) FOR ‘st’  
GIVING POSITION #LENGTH2  
COMPUTE #LENGTH = #LENGTH1 + #LENGTH2 - #PATTERNSTART + 1

Certainly not a complicated extension of the original code (basically one more  
EXAMINE SUBSTRING). By contrast, it should be noted, Weihnachtsbar’s code  
does not have to be altered at all.

In terms of CPU usage, here again is the original comparison:

PAGE # 1 DATE: Sep 08, 2006  
PROGRAM: PATTRN05 LIBRARY: SYSTEM

FAST WAY 4 37

SLOW WAY 11 64

FOR LOOP 1 5

And here is the comparison for the pattern ‘a_rn_st’

PAGE # 1 DATE: Sep 09, 2006  
PROGRAM: PATTRN06 LIBRARY: SYSTEM

FAST WAY 7 51

SLOW WAY 12 65

FOR LOOP 1 6

As before, we subtract out the FOR loop time and have a comparison between  
6 and 11 for elapsed times and 45 versus 59 for CPU times. Note that, as expected,  
the “slow way” times are virtually unchanged (basically, all that changed was  
the pattern). By contrast, the “fast way” times have increased substantially  
since we now have an additional EXAMINE SUBSTRING statement.

My guess (and until I write and test the code later, that is all it is, a guess)  
is that if we changed the required functionality yet again to provide for  
three asterisks and four “targets”, we might reach parity.

steve

---

<div class="post-metadata">

**Author:** ![Steve\_Robinson](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/steve_robinson/32/107_2.png) [@Steve\_Robinson](https://techcommunity.softwareag.com/u/Steve_Robinson)\
**Post date:** [September 10, 2006, 9:05pm UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387/6 "2006-09-10T21:05:49Z")

</div>

Mea Culpa.

The original posting by Joseph does not indicate a required functionality with but one wildcard specification. I got that from the subsequent posting by Weihnachtsbar. javascript:emoticon(‘:oops:’)  
Embarassed

steve

---

<div class="post-metadata">

**Author:** ![Eric\_Schindler](https://avatars.discourse-cdn.com/v4/letter/e/bbe5ce/32.png) [@Eric\_Schindler](https://techcommunity.softwareag.com/u/Eric_Schindler)\
**Post date:** [September 11, 2006, 1:15pm UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387/7 "2006-09-11T13:15:46Z")

</div>

nice thread…  
some hints for the fast one …

- the seperation of the search pattern into the two or more search parts is missing - would also take extra time.
- caltulating the length of of the replaced patten is little more complicated.
- the fast algorithm fails for the\*the - there is some extra work to do.
- using EXAMINE … STARTING FROM … would be more elegant and probably faster then the substring way - yes not on MF at the moment.
- and don’t forget pattern as ’ t??’ or ‘t??\*t’.

---

<div class="post-metadata">

**Author:** ![Steve\_Robinson](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/steve_robinson/32/107_2.png) [@Steve\_Robinson](https://techcommunity.softwareag.com/u/Steve_Robinson)\
**Post date:** [September 11, 2006, 7:54pm UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387/8 "2006-09-11T19:54:46Z")

</div>

Eric Schindler (one of the Site’s Moderators; thanks to all  
the Moderators for participating) wrote:

- using EXAMINE … STARTING FROM … would be more elegant and probably faster  
then the substring way - yes not on MF at the moment.

Agreed about the elegance, not the performance. When STARTING FROM was added  
to the PC Version of Natural, I did some timing tests, they turned out to be  
basically identical. My guess was that “behind the scenes” the same code is  
being generated. Perhaps it will be different when STARTING FROM is added to  
the mainframe.

- caltulating the length of of the replaced patten is little more complicated.

HOWEVER, using STARTING FROM (rather than SUBSTRING) does make the length  
calculation simple:

EXAMINE #ORIGINAL FOR ‘a’ GIVING POSITION #PATTERNSTART  
EXAMINE #ORIGINAL STARTING FROM #PATTERNSTART FOR ‘the’  
GIVING POSITION #PATTERNEND  
COMPUTE #LENGTH = #PATTERNEND - #PATTERNSTART + 3

- the fast algorithm fails for the\*the - there is some extra work to do.

Whoops, another red face Eric Schindler (one of the Site’s Moderators; thanks to all  
the Moderators for participating) wrote:

- using EXAMINE … STARTING FROM … would be more elegant and probably faster  
then the substring way - yes not on MF at the moment.

Agreed about the elegance, not the performance. When STARTING FROM was added  
to the PC Version of Natural, I did some timing tests, they turned out to be  
basically identical. My guess was that “behind the scenes” the same code is  
being generated. Perhaps it will be different when STARTING FROM is added to  
the mainframe.

- calculating the length of of the replaced patten is little more complicated.

HOWEVER, using STARTING FROM (rather than SUBSTRING) does make the length  
calculation simple:

EXAMINE #ORIGINAL FOR ‘a’ GIVING POSITION #PATTERNSTART  
EXAMINE #ORIGINAL STARTING FROM #PATTERNSTART FOR ‘the’  
GIVING POSITION #PATTERNEND  
COMPUTE #LENGTH = #PATTERNEND - #PATTERNSTART + 3

- the fast algorithm fails for the\*the - there is some extra work to do.

Whoops, another red face javascript:emoticon(‘:oops:’)  
Embarassed . In the first code I wrote for this I had

EXAMINE #ORIGINAL FOR ‘a’ GIVING POSITION #PATTERNSTART  
ADD 1 TO #PATTERNSTART  
EXAMINE SUBSTRING (#ORIGINAL,#Patternstart) FOR ‘the’  
GIVING POSITION #LENGTH  
ADD 3 TO #LENGTH  
SUBTRACT 1 FROM #PATTERNSTART  
#FOUNDPATTERN := SUBSTR(#ORIGINAL, #PATTERNSTART, #LENGTH)

When I was trying to “optimize” the code I removed the ADD/SUBTRACT to #PATTERNSTART  
forgetting why I had put them there in the first place.

I do feel that the performance differential justifies the functionality difference  
(how often will anyone require more than two asterisks anyway?).

The important point,  
I feel, is looking beyond the obvious (the PATTERN option) for other solutions.

steve

. In the first code I wrote for this I had

EXAMINE #ORIGINAL FOR ‘a’ GIVING POSITION #PATTERNSTART  
ADD 1 TO #PATTERNSTART  
EXAMINE SUBSTRING (#ORIGINAL,#Patternstart) FOR ‘the’  
GIVING POSITION #LENGTH  
ADD 3 TO #LENGTH  
SUBTRACT 1 FROM #PATTERNSTART  
#FOUNDPATTERN := SUBSTR(#ORIGINAL, #PATTERNSTART, #LENGTH)

When I was trying to “optimize” the code I removed the ADD/SUBTRACT to #PATTERNSTART  
forgetting why I had put them there in the first place.

I do feel that the performance differential justifies the functionality difference  
(how often will anyone require more than two asterisks anyway?). The important point,  
I feel, is looking beyond the obvious (the PATTERN option) for other solutions.

steve

:oops:

---

<div class="post-metadata">

**Author:** ![Steve\_Robinson](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/steve_robinson/32/107_2.png) [@Steve\_Robinson](https://techcommunity.softwareag.com/u/Steve_Robinson)\
**Post date:** [September 11, 2006, 7:56pm UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387/9 "2006-09-11T19:56:54Z")

</div>

Whoops;

a lot of extraneous text when I went to include the emoticon. sorry.

steve

---

<div class="post-metadata">

**Author:** ![Steve\_Robinson](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/steve_robinson/32/107_2.png) [@Steve\_Robinson](https://techcommunity.softwareag.com/u/Steve_Robinson)\
**Post date:** [September 11, 2006, 8:14pm UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387/10 "2006-09-11T20:14:43Z")

</div>

Here is the text without the “extra stuff”

Eric Schindler (one of the Site’s Moderators; thanks to all  
the Moderators for participating) wrote:

- using EXAMINE … STARTING FROM … would be more elegant and probably faster  
then the substring way - yes not on MF at the moment.

Agreed about the elegance, not the performance. When STARTING FROM was added  
to the PC Version of Natural, I did some timing tests, they turned out to be  
basically identical. My guess was that “behind the scenes” the same code is  
being generated. Perhaps it will be different when STARTING FROM is added to  
the mainframe.

- caltulating the length of of the replaced patten is little more complicated.

HOWEVER, using STARTING FROM (rather than SUBSTRING) does make the length  
calculation simple:

EXAMINE #ORIGINAL FOR ‘a’ GIVING POSITION #PATTERNSTART  
EXAMINE #ORIGINAL STARTING FROM #PATTERNSTART FOR ‘the’  
GIVING POSITION #PATTERNEND  
COMPUTE #LENGTH = #PATTERNEND - #PATTERNSTART + 3

- the fast algorithm fails for the\*the - there is some extra work to do.

Whoops, another red face . In the first code I wrote for this I had

EXAMINE #ORIGINAL FOR ‘a’ GIVING POSITION #PATTERNSTART  
ADD 1 TO #PATTERNSTART  
EXAMINE SUBSTRING (#ORIGINAL,#Patternstart) FOR ‘the’  
GIVING POSITION #LENGTH  
ADD 3 TO #LENGTH  
SUBTRACT 1 FROM #PATTERNSTART  
#FOUNDPATTERN := SUBSTR(#ORIGINAL, #PATTERNSTART, #LENGTH)

When I was trying to “optimize” the code I removed the ADD/SUBTRACT to #PATTERNSTART  
forgetting why I had put them there in the first place.

I do feel that the performance differential justifies the functionality difference  
(how often will anyone require more than two asterisks anyway?). The important point,  
I feel, is looking beyond the obvious (the PATTERN option) for other solutions.

steve

---

<div class="post-metadata">

**Author:** ![Eric\_Schindler](https://avatars.discourse-cdn.com/v4/letter/e/bbe5ce/32.png) [@Eric\_Schindler](https://techcommunity.softwareag.com/u/Eric_Schindler)\
**Post date:** [September 11, 2006, 8:48pm UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387/11 "2006-09-11T20:48:11Z")

</div>

Hint:

> [@](#):
>
> EXAMINE #ORIGINAL FOR ‘a’ GIVING POSITION #PATTERNSTART  
> ADD 1 TO #PATTERNSTART  
> EXAMINE SUBSTRING (#ORIGINAL,#Patternstart) …

As long as #PATTERNSTART is inside your string size it works, but if the only ‘a’ is the last character at the string … ☹  
… and if your string does not contain any ‘a’ your optimized algorithm will still find a match. :twisted:

> [@](#):
>
> I do feel that the performance differential justifies the functionality difference  
> (how often will anyone require more than two asterisks anyway?).

I very often want to find, quick and dirty, if a specific tag with attributes inside a xml document:

```auto
'<mytag*value=?this?>*</mytag'
```

and I won’t relay on quotes and white spaces:

```auto
<mytag value="this">
or
<mytag value='this'>
or
<mytag 
value='this'>
```

😉 Reliable code slow code may sometimes better then fast specialized code.

---

<div class="post-metadata">

**Author:** ![Joseph](https://avatars.discourse-cdn.com/v4/letter/j/dc4da7/32.png) [@Joseph](https://techcommunity.softwareag.com/u/Joseph)\
**Post date:** [September 12, 2006, 12:24am UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387/12 "2006-09-12T00:24:05Z")

</div>

Hi again,  
Thanks for the performance info, but it’s not so important for me at the moment.

Weihnachtsb

---

<div class="post-metadata">

**Author:** ![Steve\_Robinson](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/steve_robinson/32/107_2.png) [@Steve\_Robinson](https://techcommunity.softwareag.com/u/Steve_Robinson)\
**Post date:** [September 12, 2006, 1:21am UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387/13 "2006-09-12T01:21:45Z")

</div>

Hi Joseph;

I’d like to ask the first question again, since only Weihnachtsb

---

<div class="post-metadata">

**Author:** ![Ralph\_Zbrog](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/ralph_zbrog/32/78_2.png) [@Ralph\_Zbrog](https://techcommunity.softwareag.com/u/Ralph_Zbrog)\
**Post date:** [September 12, 2006, 1:35am UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387/14 "2006-09-12T01:35:43Z")

</div>

Natural’s MASK can find numerics and dates, but it won’t tell you the location or length of the embedded string, and the mask must be hard-coded.

Here are some examples.

```auto
DEFINE DATA LOCAL
1 #TXT (A50/10) INIT <'Search for a date, such as 08/11/06, here.'
                      ,'08/11/06 starts with a date.'
                      >
END-DEFINE
*
IF #TXT (1) = MASK (*'as 'MM'/'DD'/'YY)
  THEN 
    WRITE 'embedded: found'
  ELSE
    WRITE 'embedded: not found'
END-IF
IF #TXT (2) = MASK (*MM'/'DD'/'YY)
  THEN 
    WRITE 'starting: found'
  ELSE
    WRITE 'starting: not found'
END-IF
IF #TXT (2) = MASK (*99'/'99'/'99)
  THEN 
    WRITE 'numeric: found'
  ELSE
    WRITE 'numeric: not found'
END-IF
END
```

---

<div class="post-metadata">

**Author:** ![Weihnachtsbar](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/weihnachtsbar/32/146_2.png) [@Weihnachtsbar](https://techcommunity.softwareag.com/u/Weihnachtsbar)\
**Post date:** [September 12, 2006, 12:46pm UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387/15 "2006-09-12T12:46:06Z")

</div>

:?: Am I right, if I guess that you want to find e.g. a date pattern inside a string and then use this date for further processing?

:idea: What’s about a combination of the program I posted and the solution from “Ralph Zbrog” with MASK?

:arrow: First find a matching pattern and then crosscheck if it’s a valid date format you like.

1. I agree with “Steve Robinson” that a build in solution with the Natural language would be the easiest solution (even if it’s not the fastest).

“Ralph Zbrog” wrote:

> [@](#):
>
> …mask must be hard-coded.

From the Natural documentation about MASK Option:

> [@](#):
>
> Variable Mask  
> Apart from a constant mask-definition (see above), you may also specify a variable mask definition.  
> Syntax:  
> operand1 EQ MASK operand2

---

<div class="post-metadata">

**Author:** ![Ralph\_Zbrog](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/ralph_zbrog/32/78_2.png) [@Ralph\_Zbrog](https://techcommunity.softwareag.com/u/Ralph_Zbrog)\
**Post date:** [September 12, 2006, 1:42pm UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387/16 "2006-09-12T13:42:01Z")

</div>

Weihnachtsb

---

<div class="post-metadata">

**Author:** ![Weihnachtsbar](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/weihnachtsbar/32/146_2.png) [@Weihnachtsbar](https://techcommunity.softwareag.com/u/Weihnachtsbar)\
**Post date:** [September 12, 2006, 3:03pm UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387/17 "2006-09-12T15:03:26Z")

</div>

see:

[http://techcommunity.softwareag.com/ecosystem/documentation/natural/nat421mf/pg/pg\_furth\_lcc\_0640.htm#Variable\_Mask](http://techcommunity.softwareag.com/ecosystem/documentation/natural/nat421mf/pg/pg_furth_lcc_0640.htm#Variable_Mask)

---

<div class="post-metadata">

**Author:** ![Steve\_Robinson](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/steve_robinson/32/107_2.png) [@Steve\_Robinson](https://techcommunity.softwareag.com/u/Steve_Robinson)\
**Post date:** [September 12, 2006, 6:26pm UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387/18 "2006-09-12T18:26:03Z")

</div>

Hi Joseph;

Although I am a great fan of online lists/forums for interacting; they do have some drawbacks. One of them was in evidence from your postings. The original problem involved “finding” and “extracting” a “PATTERN”, presumably using the EXAMINE for PATTERN statement.

HOWEVER, the “refined” question, regarding “finding”, “extracting”, and “testing” for a date does not fit nicely into the solutions for the original problem. The reason is quite simple, unless we know for a fact that all dates will be eight characters in the format dd/mm/yy, a simple PATTERN search will not suffice to find and extract a date.

We would have to consider possibilities like d/m/yy, dd/m/yy, d/mm/yy, and dd/mm/yy (I am assuming, hopefully a good assumption, that this year would never be represented as just 6 rather than 06).

To find the spectrum of possibilities, you would have to find a PATTERN of /\*/ (I won’t bother to muddy the waters with other solutions that do not use PATTERN). Then you would have to “extract” at least two characters to the left and two characters to the right of the PATTERN. The characters to the right should be simple to deal with; presumably they will only be the YY.

You would now have to “look” at the character two positions to the left of the first slash. you could use an IF #LEFT-TWO = MASK (N) to see if this character is a digit.

Now you should be able to “isolate” what purports to be a date (the original pattern, two characters to the right of the pattern, and either one or two characters to the left of the pattern). Now you can final use an IF #MAYBE-DATE = MASK (DD.MM.YY) or something similar deopending on how you have isolated the “might be a date” string.

A whole lot more complicated than a simple isolate of a pattern.

steve

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/techcommunity/original/3X/c/d/cd19967bb605d28a72d77eb83a1cae22f3df2eb8.svg) [@system](https://techcommunity.softwareag.com/u/system)\
**Post date:** [April 2, 2021, 2:40pm UTC](https://techcommunity.softwareag.com/t/examine-for-pattern/61387/19 "2021-04-02T14:40:49Z")

</div>


