I found this on adv3Lite 1.5, but I checked last night and it appears the issue is still present in the latest code in GitHub.
My WIP uses several QueryTopic
instances for NPC dialog, and I was having trouble creating matchPattern
’s with regular expressions. After a bit of debugging, I found two problems:
The main issue is with the regular expression that SpecialTopic
uses to determine if a matchPattern
string is a regular expression (turtles all the way down!):
rex = static new RexPattern('<langle|rangle|star|dollar|vbar|percent|carat>')
It should be “caret,” not “carat,” which was throwing off the entire search pattern. With this bug, it appears all my regex matchPattern
’s were being processed as Mentionable
vocabulary strings (which, surprisingly, worked okay in a lot of situations, but not perfectly).
My patch is to replace the above with this:
// Fix: "caret" instead of "carat", add parentheses
rex = static new RexPattern('<langle|rangle|star|dollar|vbar|percent|caret|lparen|rparen>')
I added parentheses to the search pattern because they’re used for groupings in regex (and rarely, if ever, used in a vocab
string).
This led to being tripped up by a second issue with TopicEntry
:
/*
* If they don't want an exact case match, convert the
* original topic text to lower case
*/
if (!matchExactCase)
txt = txt.toLower();
/* if the regular expression matches, we match */
if (rexMatch(matchPattern, txt) != nil)
return matchScore + scoreBoost;
This works okay unless the regular expression is upper- or mixed-case, e.g.:
+ QueryTopic 'where' 'is (Fourth|Forth|4th) (Street|St.)'
"<q>Go around the corner,</q> he says. <q>It's between Third and Fifth Street.</q>"
;
Converting the user’s text to lowercase doesn’t help here, because the regex pattern defaults to case-sensitive. I could have gone through my code and adjusted all my existing patterns, but it seems to me that matchExactCase
should not require the coder to understand this. So, I made this change:
/*
* Fix: Use regex's case handling rather than case-folding the input text, otherwise
* matchPattern is treated as case-sensitive no matter what.
*/
local caseHandling = matchExactCase ? '<Case>' : '<NoCase>';
/* if the regular expression matches, we match */
if (rexMatch('<<caseHandling>><<matchPattern>>', txt) != nil)
return matchScore + scoreBoost;
I’m not super-excited about string-hacking regular expressions, but the above seems pretty inoffensive.
@Eric_Eve Don’t know if these changes are how you would solve the problem, so I didn’t submit a patch and am reporting it here instead. Definitely think the first problem needs attention, and feel strongly about the second.