@@ -78,15 +78,15 @@ public int match(String s, int index, MatchContext context) {
7878 }
7979 return -1 ;
8080 }
81- var i = StringUtils . indexOfIgnoreCase (s , text , index );
81+ var i = findTextWithBoundary (s , text . strip () , index );
8282 while (i != -1 ) {
8383 var toParse = s .substring (index , i ).strip ();
8484 var expression = parse (toParse , typeArray , context .getParserState (), logger );
8585 if (expression .isPresent ()) {
8686 context .addExpression (expression .get ());
8787 return index + toParse .length ();
8888 }
89- i = StringUtils . indexOfIgnoreCase (s , text , i + 1 );
89+ i = findTextWithBoundary (s , text . strip () , i + 1 );
9090 }
9191 } else if (possibleInput instanceof RegexGroup ) {
9292 var m = ((RegexGroup ) possibleInput ).getPattern ().matcher (s ).region (index , s .length ());
@@ -225,6 +225,36 @@ public int match(String s, int index, MatchContext context) {
225225 return -1 ;
226226 }
227227
228+ /**
229+ * Finds the index of text in a string, respecting word boundaries for keywords like "or", "and", "nor".
230+ * @param s the string to search in
231+ * @param text the text to find
232+ * @param start the starting index
233+ * @return the index where text was found, or -1 if not found
234+ */
235+ private int findTextWithBoundary (String s , String text , int start ) {
236+ if (text .isEmpty ()) {
237+ return -1 ;
238+ }
239+ // Check if this is a keyword that needs word boundary checking
240+ var lowerText = text .toLowerCase ();
241+ var needsBoundaryCheck = lowerText .equals ("or" ) || lowerText .equals ("and" ) || lowerText .equals ("nor" );
242+
243+ var i = StringUtils .indexOfIgnoreCase (s , text , start );
244+ while (i != -1 && needsBoundaryCheck ) {
245+ // Check word boundaries
246+ var beforeIsWordChar = i > 0 && Character .isLetterOrDigit (s .charAt (i - 1 ));
247+ var afterIsWordChar = (i + text .length () < s .length ()) && Character .isLetterOrDigit (s .charAt (i + text .length ()));
248+
249+ if (!beforeIsWordChar && !afterIsWordChar ) {
250+ return i ; // Valid word boundary match
251+ }
252+ // Try next occurrence
253+ i = StringUtils .indexOfIgnoreCase (s , text , i + 1 );
254+ }
255+ return i ;
256+ }
257+
228258 private List <String > splitAtSpaces (String s ) {
229259 List <String > split = new ArrayList <>();
230260 var sb = new StringBuilder ();
0 commit comments