1

I'm trying to implement the ideas in this post in my org. However, the provided regex seems to never match anything in any email I throw at it.

The simplest possible test case I can muster is:

string plainTextBody = 'Apex script unhandled exception by user/organization: ' + userinfo.getUserId().left(15) + '/' + userinfo.getorganizationId().left(15) + '\n';

string regex = '005[A-Za-z0-9]{12}+/(00D[A-Za-z0-9]{12}+)';

Pattern emailPattern = Pattern.compile(regex);
Matcher emailMatcher = emailPattern.matcher(plainTextBody);

for(integer i = 1; i <= emailMatcher.groupCount(); i++){
    try {
        system.debug(logginglevel.WARN, '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ emailMatcher.group(' + i + ') ' + emailMatcher.group(i));
    } catch (exception e){
        system.debug(logginglevel.WARN, '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NOTHING IN THE GROUP');
    }
}

The result of this is

14:15:26.19 (21080541)|USER_DEBUG|[12]|WARN|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NOTHING IN THE GROUP

Can anyone explain why my regex (or the one in the linked post) doesn't work "as advertised".

1

Seems I've found my own answer (after mucking around with this for nearly an hour before posting).

If I update the code to the following, all appears to work as I expect:

string plainTextBody = 'Apex script unhandled exception by user/organization: ' + userinfo.getUserId().left(15) + '/' + userinfo.getorganizationId().left(15) + '\n';

string regex = '(005[A-Za-z0-9]{12}+)/(00D[A-Za-z0-9]{12}+)';

Pattern emailPattern = Pattern.compile(regex);
Matcher emailMatcher = emailPattern.matcher(plainTextBody);

if (emailMatcher.find()){
    for(integer i = 1; i <= emailMatcher.groupCount(); i++){
        try {
            system.debug(logginglevel.WARN, '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ emailMatcher.group(' + i + ') ' + emailMatcher.group(i));
        } catch (exception e){
            system.debug(logginglevel.WARN, '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NOTHING IN THE GROUP');
        }
    }
}
  • 2
    Would you care to go over the differences between this and your original code so that others might learn from this? I can see the difference now, but it's easy to gloss over. – Derek F Oct 18 '18 at 21:28
  • Fair point. The change is that I've wrapped the for loop in 'if (emailMatcher.find()){}'. This appears to actually apply the regex to the input string, returning the different groups. – mkdjns Oct 18 '18 at 21:47
1

Your approach likely does not do what you think it does. If you want to find all partial matches in your input string, you should use this looping structure instead:

while (emailMatcher.find())               // there is another partial match
{
    String result = emailMatcher.group(); // get the entire matched string
                                          // .group() is equivalent to .group(0)
                                          // it's going to look like '005.../00D...'
    String orgId = emailMatcher.group(1);
}

If you want to get multiple matched parts within a string, that's where you might start to use .group(i), but if you are building an expression where you do not already know the groupCount, your code is too complex (you do know groupCount = 1 in your own code example). Also, never catch a generic Exception. You should not be using a catch block unless you know what type might be thrown.

Now, here's how it might look instead if you wanted to match both the User Id and the Organization Id:

String expression = '(005\\w{12})/(00D\\w{12})';
Matcher m = Pattern.compile(expression).match(plainTextBody);
while (m.find())
{
    String userId = m.group(1); // you know this grouping corresponds to 005\w{12}
    String orgId = m.group(2);  // you know this grouping corresponds to 00D\w{12}
}
  • Per the original post I linked to, the actual regex is very complex and does do what I am after. – mkdjns Oct 19 '18 at 19:20
  • The point is you are using the wrong looping structure. You should use while (emailMatcher.find()) in case there are multiple matches, then match each group by its index (starting at 1). – Adrian Larson Oct 19 '18 at 19:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.