When the above statement executes, p is assigned a pattern value. The pattern value can be used either to construct another pattern or to perform a pattern match. The patSpan function returns a pattern that matches a span of characters specified in the argument; patSpan("0123456789") matches runs of digits.
You could pre-load vehicleType with a default value if you do not want to check the outcome of the match with an if. The >? conditional assignment operator has two arguments, the first being a pattern and the second a JSL variable. >? constructs a pattern that matches the pattern (first argument) and stores the result of the match in the JSL variable (second argument) after the pattern succeeds. Similarly, >> does not wait for the pattern to succeed. As soon (and as often) as the >> pattern matches, the assignment is performed.
The above example shows a third argument in the patMatch function: the replacement string. In this case, the replacement is formed from a concatenation (|| operator) of three strings. One of the three strings, middlePart, was extracted from the testString by >? because the replacement cannot occur unless the pattern match succeeds (rc == 1).
Look at the pattern assigned to findDelimString. It is a concatenation of 3 patterns. The first is a >> operator that matches 3 characters and assigns them to beginDelim. The second is a >? operator that matches an arbitrary number of characters and, when the entire match succeeds, assigns them to middlePart. The last is an unevaluated expression, consisting of whatever string is in beginDelim at the time the pattern is executing, not at the time the pattern is built. Just like expr(), the evaluation of its argument is postponed. That makes the pattern hunt for two identical three letter delimiters of the middle part.
Other pattern functions might be faster and represent the problem that you are trying to solve better than writing a lot of alternatives; for example, "a"|"b"|"c" is the same as patAny("abc"). The equivalent example for patNotAny("abc") is much harder. Similar to patSpan (above), patBreak("0123456789") matches up to, but not including, the first number.
Sometimes data is in fixed fields. The patTab, patRTab, patLen, patPos, and patRPos functions make it easy to split out the fields in a fixed field string. PatTab and patRTab work from the left and right end of the string and take a number as their argument. They succeed by matching forward to the specified tab position. For example:
PatPos(10) matches the null string if it is in position 10. So at match time, the matcher works its way forward to position 10, then patTab(15) matches text from the current position (10) forward to position 15. This pattern is equivalent to patPos(10)+patLen(5). Another example:
This example matches the entire string, from 0 characters from the start to 0 characters from the end. the patRem() function takes no argument and is shorthand for patRTab(0); it means the remainder of the string. Pattern matching can also be anchored to the beginning of the string like this:
The above pattern uses NULL rather than a replacement value, and ANCHOR as an option. Both are uppercase, as shown. NULL means that no replacement is done. ANCHOR means that the match is anchored to the beginning of the string. The default value is UNANCHORED.
Remember, expr() is the procrastination operator; when the pattern is assigned to the variable p, expr() delays evaluating its argument (p) until later. In the next statement, patMatch performs the pattern match operation, and each time it encounters expr(), it looks for the current value of the argument. In this example, the value does not change during the match). So, if p is defined in terms of itself, how can this possibly work?
p consists of two alternatives. The right hand choice is easy: a single letter x. The left side is harder: <p*p> . Each p could be a single letter x, since that is one of the choices p could match, or it could be <p*p>. The last few example have used patPos(0) + ... + patRPos(0) to make sure the pattern matches the entire source text. Sometimes this is what you want, and sometimes you would rather the pattern match a subtext. If you are experimenting with these examples by changing the source text, you probably want to match the entire string to easily tell what was matched. The result from patMatch is 0 or 1.
If the pattern is used in FULLSCAN mode, it eventually uses up all memory as it expands. By default, the patMatch function does not use FULLSCAN, and makes some assumptions that allow the recursion to stop and the match to succeed. The pattern matches either a “b”, or anything the pattern matches followed by an “a”.