Close

Java Regex - Non Capturing Groups

[Updated: Jan 23, 2016, Created: Jan 16, 2016]

In regular expressions, the parentheses () can be used for Capturing Groups. Other than that, we just want to group multiple parts/literals to make the expression more readable. Sometimes, the parentheses are needed for alteration or applying modifiers to the group (some examples here). Not all the time we are interested in capturing groups. We can declare a group 'non-capturing' by using this syntax: (?:X). The engine will not capture any matching substring for them. It's good to use it for optimization, only if we are not interested in capturing groups.


Example:

In this example we want the part 'word' in 'password' to be optional by using the quantifier ?. It's necessary to group 'word' together by using parentheses i.e. (word)+. if we do something like this word?, we are just making the 'd' optional not the complete 'word'. In this case, we are not interested in capturing 'word' at all. That's the reason we want to make it the non-capturing group: (?:word)?

public static void main(String[] args) {
    showGroupInformation("pass(word)?", "password");
    //making the group non-capturing
    showGroupInformation("pass(?:word)?", "password");
}


public static void showGroupInformation(String regex, String input) {
    System.out.printf("Regex: %s, Input: %s%n", regex, input);
    Matcher matcher = Pattern.compile(regex).matcher(input);
    while (matcher.find()) {
        System.out.printf("Group zero, start= %s, end= %s, match= '%s'%n",
                matcher.start(), matcher.end(), matcher.group());
        for (int i = 1; i <= matcher.groupCount(); i++) {
            System.out.printf("Group number: %s, start: %s, end: %s, match= '%s'%n%n",
                    i, matcher.start(i), matcher.end(i), matcher.group(i));
        }
    }
}
/*Regex breakdown: pass(?:word)?
passLiteral part 'pass'.
(Start of group.
 ?:Declaring this group is non-capturing.
 wordListeral part 'word'.
)End of the group.
?The quantifier, matches once or not at all. This is making the preceding group optional.

*/

Output:

Regex: pass(word)?, Input: password
Group zero, start= 0, end= 8, match= 'password'
Group number: 1, start: 4, end: 8, match= 'word'

Regex: pass(?:word)?, Input: password
Group zero, start= 0, end= 8, match= 'password'

Notice there's no group captured by the engine in the second call of showGroupInformation.

Example Project


Dependencies and Technologies Used:

  • JDK 1.8
  • Maven 3.0.4

Non Capturing Groups Select All Download
  • regex-non-capturing-groups
    • src
      • main
        • java
          • com
            • logicbig
              • example

See Also