Team LiB
Previous Section Next Section

Possessive Qualifiers

Given the context of greedy qualifiers, possessive qualifiers are relatively easy to understand. They're unique to Java, though they'll probably be adopted by other regex languages in time. Simply put, they're greedy, but never generous. Adding a plus sign (+) after an existing greedy qualifier forms a possessive qualifier. Thus, \d+ becomes \d++, \d{n,m} becomes \d{n,m}+, and so on.

Consider the previous example in which the pattern (\w+)(\d\d)(\w+) is applied to the candidate string X99SuperJava. I established earlier that the regex engine, when faced with the group (\w+), would attempt to match as many characters as possible. I also established that it would release those matches if such a release would help a later group achieve a match.

If you don't want the group to release its matches to help later groups match, however, then you would use possessive qualifiers simply by following your last expression with an additional plus sign. You form the pattern (\w++)(\d\d)(\w+)—that is, you turn \w+ into \w++.

When the pattern is first run, group(1), namely (\w++), consumes every character in the candidate X99SuperJava. However, because of the existence of the second plus sign, the engine refuses to release any of those matching characters to help the following groups match. You find that group(1) matches, and group(2) and group(3) don't—the regex as whole doesn't match. Listing 3-6 demonstrates this.

Listing 3-6: Possessive Qualifier Example
Start example
import java.util.regex.*;

public class PossesiveExample{
    public static void main(String args[]){
        //define the pattern
        String regex = "(\\w++)(\\d\\d)(\\w+)";
        //compile the pattern
        Pattern pattern = Pattern.compile(regex);

        //define the candidate string
        String candidate = "X99SuperJava";

        //extract a matcher for the candidate string
        Matcher matcher = pattern.matcher(candidate);

        if (matcher.find()){
            System.out.println("GROUP 0:" +
            matcher.group(0));
            System.out.println("GROUP 1:" +
            matcher.group(1));
            System.out.println("GROUP 2:" + matcher.group(2));
            System.out.println("GROUP 3:" + matcher.group(3));
        }
        else{
           System.out.println("NO MATCHES" );
        }

        System.out.println("Done");
    }
}

End example

Team LiB
Previous Section Next Section