0

I am trying to dynamically match a string against other string.

String badWord = 'badwords';
String comment = 'I talk badwords and goodwords';
Pattern MyPattern = Pattern.compile('((.*)('+badWord+')(.*))');
Matcher MyMatcher = MyPattern.matcher(comment);
System.debug('matcher '+MyMatcher);
while(MyMatcher.find()){
   System.debug(MyMatcher.group());  
}

I assumed atleast 4 groups to be matched against, however I get only one group and that too full string.

I talk badwords and goodwords
2
  • 2
    The pattern matcher implementation is somewhat limited in Apex. Why do you need to capture the parts of the string that are not the "bad words"?
    – Phil W
    Apr 3, 2022 at 9:02
  • @PhilW I want to get location of "bad words" so that I can highlight it in later contexts
    – AmanSharma
    Apr 4, 2022 at 5:38

1 Answer 1

3

You did get four groups, you just didn't check for them. The group() method returns group(0), which matches outer parentheses group. To get the full picture, you'd check out:

while(MyMatcher.find()){
    for(Integer i = 0, s = MyMatcher.groupCount(); i <= s; i++) {
        System.debug(MyMatcher.group(i));  
    }
}

Which gives you:

USER_DEBUG|[8]|DEBUG|I talk badwords and goodwords
USER_DEBUG|[8]|DEBUG|I talk badwords and goodwords
USER_DEBUG|[8]|DEBUG|I talk 
USER_DEBUG|[8]|DEBUG|badwords
USER_DEBUG|[8]|DEBUG| and goodwords

Where group(0) gives you the complete match, group(1) matches the outer parentheses (the first capture group), group(2) matches the first inner parentheses, group(3) gives you the badwords, and group(4) captures the last capture group.

This output is essentially the same as it is in JavaScript.

If you want to match all of the badwords, don't use the outer capture groups with find().

Pattern MyPattern = Pattern.compile('('+badWord+')');

Doing this will get you just the badwords, and using the start() method will tell you the starting offset of the previous match from find().

If you instead want to find all of the matches one at a time, the pattern should be:

Pattern MyPattern = Pattern.compile('(.*?)('+badWord+')');

Which gives the output:

USER_DEBUG|[8]|DEBUG|I talk badwords
USER_DEBUG|[8]|DEBUG|I talk 
USER_DEBUG|[8]|DEBUG|badwords

If there were more matches for badwords, you'd get successive strings in the order (goodwords)(badwords).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .