home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 18 REXX
/
18-REXX.zip
/
rxregexp.zip
/
rxregexp.ipf
< prev
next >
Wrap
Text File
|
1998-04-14
|
13KB
|
346 lines
.*---------------------------------------------------------------------------
.* A.N.Z. Bank Confidential
.*
.* MODULE NAME: RxRegExp.IPF
.*
.* $Author: Dennis_Bareis $
.* $Revision: 1.1 $
.* $Date: 09 Aug 1996 15:55:54 $
.* $Logfile: Q:/PVCSDATA/SUPPORT/SUPPORT/TEMPLATE.IPV $
.*
.* DESCRIPTION:
.*
.*---------------------------------------------------------------------------
.im IPFGEN.IPF
:userdoc.
:Title.Regular Expressions For REXX (<$IpfTimeVersion?>)
:docprof toc=123456.
.*===========================================================================
:Heading p1='Introduction' p2='Introduction'.
.*===========================================================================
:i1 id=Introduction.Introduction
:BigTitle p1='Introduction'.
:p.The "RxRegExp.DLL" code allows any rexx program to make fast
extensive use of
:LinkToText p1='RegularExpression' p2='regular expression'.
searches and replaces.
:p.The original regular expession "engine" (which was not modified) was
written by "Henry&rbl.Spencer" (henry@zoo.toronto.edu). There is no version
number on this source that I can find although the doco is dated
"5&rbl.Sept&rbl.1996".
:p.I have provided a
:LinkToText p1='Example' p2='sample rexx program'. which should help
you get started.
:p.The DLL was written by "Dennis&rbl.Bareis" (:Bold p1='db0@anz.com'.), the
latest code can be obtained from my web page at
":Bold p1='http&colon.//www.ozemail.com.au/~dbareis'.".
.*===========================================================================
:Heading p1='RegularExpression' p2='Regular Expressions'.
.*===========================================================================
:i1 id=RegularExpression.Regular Expressions
:p.The following description is based on the documentation written by
"Henry&rbl.Spencer" (henry@zoo.toronto.edu).
:BigTitle p1='Regular Expressions'.
:p.A regular expression is a sequence of characters which describes
what we are searching for.
:p.A regular expression is zero or more :DarkGreen p1='branches'.
separated by ":Red p1='|'.". It matches anything that matches one
of the branches.
:p.A branch is zero or more :DarkGreen p1='pieces'., concatenated.
It matches a match for the first, followed by a match for the second, etc.
:p.A piece is an :DarkGreen p1='atom'. possibly followed by "*", "+", or
"?" where&colon.
:UnNumberedListCompact.
:li.An atom followed by ":Red p1='*'." matches a sequence of 0 or more matches of the atom.
:li.An atom followed by ":Red p1='+'." matches a sequence of 1 or more matches of the atom.
:li.An atom followed by ":Red p1='?'." matches a match of the atom, or the null string.
:eUnNumberedListCompact.
:p.An atom is&colon.
:UnNumberedList.
:li.A regular expression in parentheses (matching a match for the
regular expression), a :DarkGreen p1='range'. (see below).
:li.":Red p1='&per.'." which matches any single character.
:li.":Red p1='^'." which matches the empty string at the start of a
line.
:li.":Red p1='$'." which matches the empty string at the end of a
line.
:li.":Red p1='\e'." (a slash followed by a character) which matches
the character. This is needed so search for "$" etc!
:li.A single character with no other significance matches that
character.
:eUnNumberedList.
:p.A range is a sequence of characters enclosed in ":Red p1='[]'.".
It normally matches any single character from the sequence.
If the sequence begins with ":Red p1='^'.", it matches any single
character :Bold p1='not'. from the rest of the sequence. If two characters
in the sequence are separated by ":Red p1='-'." then this is shorthand
for the full list of ASCII characters between them (e.g. "[0-9]"
matches any decimal digit). To include a literal "]" in the
sequence, make it the first character (following a
possible "^"). To include a literal "-", make it the first
or last character.
:BigTitle p1='AMBIGUITY'.
:p.If a regular expression could match two different parts of the input string,
it will match the one which begins earliest. If both begin in the same place
but match different lengths, or match the same length in different
ways, life gets messier, as follows&colon.
:UnNumberedList.
:li.In general, the possibilities in a list of branches are considered in
left-to-right order, the possibilities for "*", "+", and "?" are
considered longest-first, nested constructs are considered from the
outermost in, and concatenated constructs are considered leftmost-first.
The match that will be chosen is the one that uses the earliest
possibility in the first choice that has to be made.
If there is more than one choice, the next will be made in the same manner
(earliest possibility) subject to the decision on the first choice.
And so forth.
:p.For example, "(ab|a)b*c" could match "abc" in one of two ways.
The first choice is between "ab" and "a"; since "ab" is earlier, and does
lead to a successful overall match, it is chosen.
Since the "b" is already spoken for,
the "b*" must match its last possibility (the empty string) since
it must respect the earlier choice.
:li.In the particular case where the regular expression does not use
"|" and does not apply "*", "+", or "?" to parenthesized subexpressions,
the net effect is that the longest possible match will be chosen.
So "ab*", presented with "xabbbby", will match "abbbb".
Note that if "ab*" is tried against "xabyabbbz", it
will match "ab" just after "x", due to the begins-earliest rule.
In effect, the decision on where to start the match is the first choice
to be made, hence subsequent choices must respect it even if this leads them
to less-preferred alternatives.
:eUnNumberedList.
.*===========================================================================
:Heading p1='Commands' p2='Commands'.
:HeadingLevelDown.
.*===========================================================================
:i1 id=Commands.Commands
:BigTitle p1='Commands'.
:p.The following functions are available&colon.
:UnNumberedListCompact.
:li.:LinkTo p1='RegExpVersion'.
:li.:LinkTo p1='RegExpCompile'.
:li.:LinkTo p1='RegExpMatch'.
:li.:LinkTo p1='RegExpReplace'.
:eUnNumberedListCompact.
:p.Note that you can't trust the return codes from rexx
add/query/drop functions so if you wish to detect (instead of dying)
that the DLL is unavailable you should check my
:LinkToText p1='Example' p2='sample rexx program'. which contains a
subroutine which does this.
.dm SampleAndReturnCodeInfo on
:p.Please see my :LinkToText p1='Example' p2='sample rexx program'.
for an example of this call in use.
:BigTitle p1='Returns'.
:p.This routine returns ":Red p1='OK'." if the call succeeds
otherwise it returns text which describes the reason for the failure.
.dm off
.*===========================================================================
:Heading p1='RegExpVersion' p2='RegExpVersion'.
.*===========================================================================
:i2 refid=Commands.RegExpVersion
:BigTitle p1='RegExpVersion'.
:p.This routine will allow you to determine the version and author
information of the DLL you are using.
:p.The routine takes a single parameter as follows&colon.
:OrdListCompact.
:li.Name of Variable to update with version Information.
:eOrdListCompact.
:p.The information returned (seperated by a single space)&colon.
:OrdListCompact.
:li.Version Number such as "98.104".
:li.My Web page URL (where you can get a later version if available).
:li.My email Address.
:li.My Name.
:eOrdListCompact.
:SampleAndReturnCodeInfo.
.*===========================================================================
:Heading p1='RegExpCompile' p2='RegExpCompile'.
.*===========================================================================
:i2 refid=Commands.RegExpCompile
:BigTitle p1='RegExpCompile'.
:p.To make use of a
:LinkToText p1='RegularExpression' p2='regular expression'.
it must first be compiled.
This routine will either compile a regular expression or release any
memory associated with the last compiled regular expression.
:p.The routine takes a single parameter as follows&colon.
:OrdListCompact.
:li.The regular expression to be compiled. There is one exception,
if you pass exactly ":Red p1='ReClose'." then this is taken to be a
close off previous regular expression command.
:eOrdListCompact.
:p.The compiled express (plus some other bits) are held in memory
until released. Rexx programs running in different sessions will not
interfere with each other. Not sure if there can be any problems
within a session but I suspect not.
:SampleAndReturnCodeInfo.
.*===========================================================================
:Heading p1='RegExpMatch' p2='RegExpMatch'.
.*===========================================================================
:i2 refid=Commands.RegExpMatch
:BigTitle p1='RegExpMatch'.
:p.This routine will attempt to find a
:LinkToText p1='RegularExpression' p2='regular expression'.
which was previously
:LinkToText p1='RegExpCompile' p2='compiled'..
:p.The routine takes 2 parameters as follows&colon.
:OrdListCompact.
:li.The string to be searched.
:li.Name of Variable to update with match details. If the variable
is blank then there was no match otherwise a set of one or more
":DarkGreen p1='match&rbl.pairs'." is returned.
:eOrdListCompact.
:BigTitle p1='Match Pairs'.
:p.In a set of match pairs the first describes the location of the
overall regular expression while any others (if they exist) describe
the location of any matches for expressions that
occurred between round brackets in the regular expression.
:p.Each match pair describes the starting position (1st byte is 1) and
the length of the match.
:p.If you used the regular expression "(A)(B)" on the string "ABCDEF"
then "1&rbl.2&rbl.1&rbl.1&rbl.2&rbl.1" would be returned.
:SampleAndReturnCodeInfo.
.*===========================================================================
:Heading p1='RegExpReplace' p2='RegExpReplace'.
.*===========================================================================
:i2 refid=Commands.RegExpReplace
:BigTitle p1='RegExpReplace'.
:p.This routine will modify a string you supply based on the
:LinkToText p1='RegExpMatch' p2='match information'. from
a previous
:LinkToText p1='RegularExpression' p2='regular expression'..
:p.The routine takes 2 parameters as follows&colon.
:OrdListCompact.
:li.The replace specification.
:li.Name of Variable which will contain the modified string.
:eOrdListCompact.
:BigTitle p1='Replace Specification'.
:p.The first thing you should understand is that we are not
performing and sort of normal search and replace here, we are taking
a specification and building a new string. If you wanted to perform
a search and replace type operation you would need to use round
brackets and ensure that the before and after match strings were
described. Note that doing this can vary the match location of the
string you are trying to match!
:p.The replace specification is basically a string where any
occurrance of ":Red p1='&.'." or ":Red p1='\0'." is replaced with the overall matched
characters. ":Red p1='\1'." to ":Red p1='\9'." are replaced with the
appropriate match information for each round bracketed expression
('\1' is first one).
:p.For example you may wish to replace "SET" with "set" in which case
you could have used the regular expression "SET" to search for the
string with ":LinkTo p1='RegExpMatch'.", however this would not be
useful unless you manually wrote code to do the replacement (not
hard), to use this "replace" routine you would search with something
like "(^.*)SET(.*$)" and then your replace specification could be
"\1set\2".
:SampleAndReturnCodeInfo.
.*===========================================================================
:HeadingLevelUp.
:Heading p1='Example' p2='Rexx Example'.
.*===========================================================================
:i1 id=Example.Rexx Example
:BigTitle p1='Rexx Example'.
$DefineTextChanges `RegExpVersion` `:LinkTo p1='RegExpVersion'.`
$DefineTextChanges `RegExpCompile` `:LinkTo p1='RegExpCompile'.`
$DefineTextChanges `RegExpMatch` `:LinkTo p1='RegExpMatch'.`
$DefineTextChanges `RegExpReplace` `:LinkTo p1='RegExpReplace'.`
:Example.
.im TestRe.CMD
:eExample.
:euserdoc.