Quantifiers in Java

We strongly recommend to refer below post as a prerequisite of this.

Regular Expressions in Java

Quantifiers allow user to specify the number of occurrences to match against. Below are some commonly used quantifiers in Java.

X*        Zero or more occurrences of X
X?        Zero or One occurrences of X
X+        One or More occurrences of X
X{n}      Exactly n occurrences of X 
X{n, }    At-least n occurrences of X
X{n, m}   Count of occurrences of X is from n to m

The above quantifiers can be made Greedy, Reluctant and Possessive.

Greedy quantifier (Default)
By default, quantifiers are Greedy. Greedy quantifiers try to match the longest text that matches given pattern. Greedy quantifiers work by first reading the entire string before trying any match. If the entire text doesn’t match, remove last character and try again, repeating the process until a match is found.



// Java program to demonstrate Greedy Quantifiers
import java.util.regex.Matcher;
import java.util.regex.Pattern;
   
class Test
{
    public static void main(String[] args)
    {
        // Making an instance of Pattern class
        // By default quantifier "+" is Greedy
        Pattern p = Pattern.compile("g+");
   
        // Making an instance of Matcher class
        Matcher m = p.matcher("ggg");
   
        while (m.find())
            System.out.println("Pattern found from " + m.start() +
                               " to " + (m.end()-1));
   
    }
}

Output :

Pattern found from 0 to 2

Explanation : The pattern g+ means one or more occurrences of g. Text is ggg. The greedy matcher would match the longest text even if parts of matching text also match. In this example, g and gg also match, but the greedy matcher produces ggg.



Reluctant quantifier (Appending a ? after quantifier)
This quantifier uses the approach that is opposite of greedy quantifiers. It starts from first character and processes one character at a time.

// Java program to demonstrate Reluctant Quantifiers
import java.util.regex.Matcher;
import java.util.regex.Pattern;
   
class Test
{
    public static void main(String[] args)
    {
        // Making an instance of Pattern class
        // Here "+" is a Reluctant quantifier because
        // a "?' is appended after it.
        Pattern p = Pattern.compile("g+?");
   
        // Making an instance of Matcher class
        Matcher m = p.matcher("ggg");
   
        while (m.find())
            System.out.println("Pattern found from " + m.start() +
                               " to " + (m.end()-1));
   
    }
}

Output :

Pattern found from 0 to 0
Pattern found from 1 to 1
Pattern found from 2 to 2

Explanation : Since the quantifier is reluctant, it matches the shortest part of test with pattern. It processes one character at a time.



Possessive quantifier (Appending a + after quantifier)
This quantifier matches as many characters as it can like greedy quantifier. But if the entire string doesn’t match, then it doesn’t try removing characters from end.

// Java program to demonstrate Possessive Quantifiers
import java.util.regex.Matcher;
import java.util.regex.Pattern;
   
class Test
{
    public static void main(String[] args)
    {
        // Making an instance of Pattern class
        // Here "+" is a Possessive quantifier because
        // a "+' is appended after it.
        Pattern p = Pattern.compile("g++");
   
        // Making an instance of Matcher class
        Matcher m = p.matcher("ggg");
   
        while (m.find())
            System.out.println("Pattern found from " + m.start() +
                               " to " + (m.end()-1)); 
    }
}

Output :

Pattern found from 0 to 2

Explanation: We get the same output as Greedy because whole text matches the pattern.

Below is an example to show difference between Greedy and Possessive Quantifiers.

// Java program to demonstrate difference between Possessive and 
// Greedy Quantifiers
import java.util.regex.Matcher;
import java.util.regex.Pattern;
   
class Test
{
    public static void main(String[] args)
    {
        // Create a pattern with Greedy quantifier
        Pattern pg = Pattern.compile("g+g");
  
        // Create same pattern with possessive quantifier
        Pattern pp = Pattern.compile("g++g");         
  
        System.out.println("Using Greedy Quantifier");
        Matcher mg = pg.matcher("ggg"); 
        while (mg.find())
            System.out.println("Pattern found from " + mg.start() +
                               " to " + (mg.end()-1)); 
  
        System.out.println("\nUsing Possessive Quantifier");
        Matcher mp = pp.matcher("ggg"); 
        while (mp.find())
            System.out.println("Pattern found from " + mp.start() +
                               " to " + (mp.end()-1)); 
  
    }
}

Output :

Using Greedy Quantifier
Pattern found from 0 to 2

Using Possessive Quantifier

In the above example, since first quantifier is greedy, g+ matches with whole string. If we match g+ with whole string, g+g doesn’t match, the Greedy quantifier, removes last character, matches gg with g+ and finds a match.
In Possessive quantifier, we start like Greedy. g+ matches whole string, but matching g+ with whole string doesn’t match g+g with ggg. Unlike Greedy, since quantifier is possessive, we stop at this point.

This article is contributed by Rahul Agarwal. If you like GeeksforGeeks and would like to contribute, you can also write an article and mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above



My Personal Notes arrow_drop_up


Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.