Make regular expression (regex) capturing groups work in Salesforce Apex

Make regular expression (regex) capturing groups work in Salesforce Apex.

Regex capturing groups allow you to refer to specific segments of matched text in regular expressions.  Consider, for instance, the following JSON string:

String text =
 '{ "First Name": "Huckleberry", "Last Name": "Finn" }';

One way to get the value associated with “Last Name” is to use a regex capturing group.

In regular expression syntax, capturing groups are denoted with parentheses.  To capture the string ‘Finn’ from this example, we can use the following regular expression:

String regex = '^.*"Last Name": "([^"]*)".*$';

Salesforce Apex uses the Pattern and Matcher classes from Java for parsing regular expressions. The Pattern class stores and manages regex patterns.  The Matcher class stores the results of an attempt to match a Pattern with a String, including any captured text.

The following line of Apex will store the information about the attempted match in a variable:

Matcher m = Pattern.compile(regex).matcher(text);

You can use the [Matcher].group([Integer]) method to get any captured String from a Matcher object.

If you want to capture the string ‘Finn’ and print it to the debug log, you might expect the following code segment to work:

String text =
 '{ "First Name": "Huckleberry", "Last Name": "Finn" }';
String regex = '^.*"Last Name": "([^"]*)".*$';
Matcher m = Pattern.compile(regex).matcher(text);
System.debug(m.group(1));

But instead you get the following error:

System.StringException: No match found

You will get this error regardless of whether there was a match or not.

The fix is to wrap the reference to the captured group in an if statement that checks for a match:

String regex = '^.*"Last Name": "([^"]*)".*$';
String text =
 '{ "First Name": "Huckleberry", "Last Name": "Finn" }';
Matcher m = Pattern.compile(regex).matcher(text);

if(m.matches()) {
  System.debug(m.group(1));
}

It is possible to capture more than one group and you can even nest capturing groups, as shown in this Salesforce help page.

The take away from this post, though, is that you need to check for a match before you try to access captured text.

–SC

Read more about Salesforce Development