VERSIONS: All
SUBJECT: advMatch()
BY: MARK PAUKER
QUESTION:
It seems advmatch() will always assign the last instance that matches the conditions. Is there anyway to make it assign the first?
var
st,stNextparm string
endvar
st="started on <D1>. Finished on <D2>. Turned in on <D3>"
if advmatch(st,"<D1>..[(@@)]",stNextparm) then
stNextparm.view() ; always is "D3"
endif
The problem that you are running into is that the ".." wildcard specifier attempts to match as many characters as possible (as opposed to PdoxDOS
where it attempts to match as few as possible). I usually try to use the "not" operator to do what you are attempting. For example, I might attempt
to solve your problem as follows: (Note that I have changed your square brackets to angle brackets because square brackets have special meaning
to advMatch. To do what you want with square brackets would require using backslashes to tell Paradox to treat the brackets as literals, and those
backslashes would only detract from the concept I'm trying to demonstrate.)
st = "started on <D1>. Finished on <D2>. Turned in on <D3>"
if st.advMatch("<D1>[^<]*<(@@)>", stNextParm)
sNextParm.view()
endIf
My match string reads as follows: Find the characters "<D1>" followed by any number of characters that are not "<", followed by
something in the form of "<@@>", where "@@" can be any two characters. Additionally, bind the characters that matched the "@@" pattern to
the variable nextParm.
I realize that this is not perfect, as it would not match the string:
"started on <D1>. Finished in <4 days on <D2>. Turned in on <D3>"
because the "<" in "<4" would get in the way. Nonetheless, this is almost never a problem in the contexts that I use this technique, and if
it were, I could do a bit more manipulation to get around it.
It was the '..' that was the problem. I tried '[^}]' but got nowhere. I still don't understand the meaning of '*','+', and '?'. Help identifies them
but doesn't explain very well or use them in an example. I've just started using advmatch. It's very powerful and I'm using it to make up for PfW5's
shortcomings in string manipulation.
Those are actually pretty simple. If you use "xyx" as a match string, you are telling Paradox to match "x", followed by "y", followed by "x".
Thus it will only match "xyx".
If you use "xy*x", then Paradox will match "x", followed by as many "y" characters as possible, followed by "x". This form also makes the "y"
optional. (That is, it must match 0-n times.) Thus it will match "xx", "xyx", or "xyyyx".
Using "xy+x" says that the "y" must match at least once. Thus it is the same as "xy*x", except that it will not match the string "xx".
"xy?x" simply makes the "y" optional. This pattern will match "xx" and "xyx", but will not match "xyyyx".
The most confusing thing about these characters is that they don't work in conjunction with groupings. That is, I expect the pattern "w(xy)*z"
to match "wz", "wxyz", "wxyxyz", etc. The problem is that the pattern doesn't work as expected. I don't know if this is a WAD or a bug, but I've
reported it to Borland, and I'll just wait and see.
VERSION: All
SUBJECT: Checking for characters ..
BY: A. I. BREVELERI
Date: 10 September 2001
How to find an instance of '..' in a string
This advMatch pattern will find an instance of '..' in a string:
if st1.advmatch("^(..)\\.\\.(..)$",st2,st3) then
{ st2 now has contents of st1 up to the last '..' }
{ note that st2 may contain more '..'s }
{ st3 now has contents of st1 after the last '..' }
else
{ st1 didn't contain any '..' }
endif
Similarly, this pattern will find an instance of '@':
if st1.advmatch("^(..)\\@(..)$",st2,st3) then
if st1.advmatch("^(..)\\@(..)$",st2,st3) then
{ st2 now has contents of st1 up to the last '@' }
{ note that st2 may contain more '@'s }
{ st3 now has contents of st1 after the last '@' }
else
{ st1 didn't contain any '@' }
endif
VERSIONS: All
SUBJECT: Accept only digits and letters
BY: KEN LOOMIS
Date: Wed, 29 May 2002
QUESTION:
I have a one letter string and would like to know if it's an odd character (other than normal letters and number)
What's the easiest way to do this?
if stBewerk.advMatch("([^0-9a-zA-Z])", stText) then
stText.view("It's odd")
endif
VERSIONS: All
SUBJECT: FYI: Advmatch fun the not match [^
BY: MARK BANNISTER
Date: 6 september 2005
I thought I would share this match string. It is the power of the NOT search over the match anything "..".
Match anything ("..") is typically the least useful of all the advmatch commands. Consider parsing out html commands from this line:
"This is the <big>test</big> of parsing <small>commands</small>."
An advmatch of "<(..)>" would result in "big>test</big> of parsing <small>commands</small", matching from the very
first "<" to the very last ">" in the compare text. On the other hand this match "<([^>]*)" yields "big". Broken down the match is:
< - find the first "<"
( - start collecting after the the first "<"
[^>] - do NOT match the ">" character
* - match zero or more characters that are not ">" IMPORTANT
) - end of match
The result is it will match all characters after the "<" until the next ">" is encountered.
Now what would happen if you wanted to get all the text before the first tag and all the text after?
The match is "([^<]*)<([^>]*)(..)"
Which says now has three parts which are:
([^<]*) - 1. match zero or more characters that are NOT the "<"
<([^>]*) - 2. this is the same as above to match the tag
(..) - 3. match anything after the ">" character of the match before
This match would result in:
1="This is the "
2="big"
3=">test</big> of parsing <small>commands</small>."
Notice that I am not catching the "<" but do catch the ">". You could add the "<" to the match by moving the "(" to include it
"([^<]*)(<[^>]*)(..)" and the result would be:
1="This is the "
2="<big" --only difference is the "<"
3=">test</big> of parsing <small>commands</small>."
This technique can be usefully to match things that do not cross the end of line mark. This match "([^\n]*)" matches an entire line up to the
"\n" (new line).
To make advmatch testing easier I put together a little form for testing advmatches. If you do much advmatch work at all it is very handy. It
does have one bug that I know of. If you don't include any () params it will fail. You can get it here
http://www.injection-moldings.com/codesamples/advmatchtest.fsl