0

You can get some context here on my previous post.

When I run the below code on execute anonymous, it renders the following result:

String txt = 'Requesting service for Id Number 9202204720082, Case C - 12246503 and passport A01524783';
String regex = '[ADMT]\\d{8}|\\d{2}[01]\\d[0-3]\\d ?\\d{4} ?[01]8 ?\\d|(?i)C - \\d{8}';
System.debug('========' + regex);
Matcher thematcher = Pattern.compile(regex).matcher(txt);
String idno = (thematcher.find()) ? thematcher.group() : '';
System.debug('========= ' + idno);

enter image description here

When I call the class from execute anonymous:

String txt = 'Requesting service for Id Number 9202204720082';
String regex = '[ADMT]\\d{8}|\\d{2}[01]\\d[0-3]\\d ?\\d{4} ?[01]8 ?\\d|(?i)C - \\d{8}';
System.debug('========' + new EmailLinker(new Messaging.InboundEmail()).findMatch(txt, regex));

enter image description here

If I call the class directly from the backend:

public String findMatch(
    String emailContent,
    String criteriaValue
) {
    String idNumber = '';
    criteriaValue = criteriaValue.unescapeHtml4();
    System.debug('======== Criteria ' + criteriaValue);
    System.debug('======== content ' + emailContent);
    Matcher emailMatcher = Pattern.compile(criteriaValue).matcher(emailContent);
    System.debug('======== email match ' + emailMatcher.find());
    Boolean isFound = Boolean.valueOf(emailMatcher.find());
    //if (isFound == true) {
        System.debug('======== ID ' + emailMatcher.group());
        idNumber = emailMatcher.group();
    //}
    System.debug('======== ID ' + idNumber);
    return idNumber;
}

enter image description here

What am I missing here? Any help is appreciated.

Edit: As per the comment

public String findMatch(
        String emailContent,
        String criteriaValue
    ) {
        String idNumber = '';
        criteriaValue = criteriaValue.unescapeHtml4();
        System.debug('======== Criteria ' + criteriaValue);// [ADMT]\\d{8}|\\d{2}[01]\\d[0-3]\\d ?\\d{4} ?[01]8 ?\\d|(?i)C - \\d{8}
        System.debug('======== content ' + emailContent);
        Matcher emailMatcher = Pattern.compile(criteriaValue).matcher(emailContent);
        if (emailMatcher.find()) {
            System.debug('======== ID ' + emailMatcher.group());
            idNumber = emailMatcher.group();
        }
        System.debug('======== ID ' + idNumber);
        return idNumber;
    }

This is still not working, it only works when I hardcode the regex pattern, and can't do that as it is dynamic.

1
  • remove your System.debug('======== email match ' + emailMatcher.find()); line Commented Mar 24, 2023 at 10:56

2 Answers 2

1

According to doc

find() Attempts to find the next subsequence of the input sequence that matches the pattern. This method returns true if a subsequence of the input sequence matches this Matcher object's pattern.

hence if you call find() twice, one from Systm.debug another from code., it will try to find next to next sequence, which will fail.

Thus removing Boolean isFound = Boolean.valueOf(emailMatcher.find()); from code should work fine.

I replicated your scenario like this:

public with sharing class EmailLinker {

    public String findMatch(
            String emailContent,
            String criteriaValue) {
        String idNumber = '';
        criteriaValue = criteriaValue.unescapeHtml4();
        System.debug('======== Criteria ' + criteriaValue);
        System.debug('======== content ' + emailContent);
        Matcher emailMatcher = Pattern.compile(criteriaValue).matcher(emailContent);
        System.debug('======== email match ' + emailMatcher.find());

        //if (isFound == true) {
        System.debug('======== ID ' + emailMatcher.group());
        idNumber = emailMatcher.group();
        //}
        System.debug('======== ID ' + idNumber);
        return idNumber;
    }

}

Anonymouos apex :

String txt = 'Requesting service for Id Number 9202204720082';
String regex = '[ADMT]\\d{8}|\\d{2}[01]\\d[0-3]\\d ?\\d{4} ?[01]8 ?\\d|(?i)C - \\d{8}';
System.debug('========' + new EmailLinker().findMatch(txt, regex));

Shows:

16:29:00.168 (179827998)|USER_DEBUG|[8]|DEBUG|======== Criteria [ADMT]\d{8}|\d{2}[01]\d[0-3]\d ?\d{4} ?[01]8 ?\d|(?i)C - \d{8} 16:29:00.168 (179898844)|USER_DEBUG|[9]|DEBUG|======== content Requesting service for Id Number 9202204720082 16:29:00.168 (184007884)|USER_DEBUG|[11]|DEBUG|======== email match true 16:29:00.168 (184074021)|USER_DEBUG|[14]|DEBUG|======== ID 9202204720082 16:29:00.168 (184103751)|USER_DEBUG|[17]|DEBUG|======== ID 9202204720082 16:29:00.168 (184134185)|USER_DEBUG|[3]|DEBUG|========9202204720082

7
  • That is helpful, thanks! But if you call the EmaiLinker class from a trigger or another piece of automation it won't work. In my case it is not working from a backend call i.e. I'm calling the EmailLinker class from an InboundEmailService class. From exec anon it does work, but not from apex class.
    – d_k
    Commented Mar 24, 2023 at 11:27
  • It will work, try removing one of the find methods and keep only one. Commented Mar 24, 2023 at 11:35
  • It doesn't work - I will add my code as an edit to the question so that you can view it.
    – d_k
    Commented Mar 24, 2023 at 13:22
  • @d_k When you say it doesn't work, what do you mean, still getting the exception? Commented Mar 25, 2023 at 4:20
  • No, emailMatcher.group() returns nothing. It only works when the regex is hardcoded.
    – d_k
    Commented Mar 25, 2023 at 8:31
1

The Apex compiler requires certain characters to be escaped in order to work. This is mentioned in Primitive Data Types:

EscapeSequences: All Strings in Apex use the same escape sequences as SOQL strings: \b (backspace), \t (tab), \n (line feed), \f (form feed), \r (carriage return), " (double quote), ' (single quote), and \ (backslash).

Further, regular expressions also use \ for its own escape sequences.

Subsequently, this means that you need to escape any \ that you want to put into your Apex source code to get them to the regular expression engine.

Pattern p = Pattern.compile('\\bHello\\b');

Matches the full word Hello (\b is the word-border matching pattern in regular expressions).

When your data comes from another place other than Apex source code, you don't need to escape it. This includes reading from a field, a static resource, an email body, and so on. The extra escape sequence is only for Apex source code.

You must log in to answer this question.

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