The issue you're having is with the type of quantifier. You're using a greedy quantifier in your first group (index 1 - index 0 represents the whole Pattern), which means it'll match as much as it can (and since it's any character, it'll match as many characters as there are in order to fulfill the condition for the next groups).

In short, your 1st group .* matches anything as long as the next group \\d+ can match something (in this case, the last digit).

As per the 3rd group, it will match anything after the last digit.

If you change it to a reluctant quantifier in your 1st group, you'll get the result I suppose you are expecting, that is, the 3000 part.

Note the question mark in the 1st group.

String line = "This order was placed for QT3000! OK?";
Pattern pattern = Pattern.compile("(.*?)(\\d+)(.*)");
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
    System.out.println("group 1: " + matcher.group(1));
    System.out.println("group 2: " + matcher.group(2));
    System.out.println("group 3: " + matcher.group(3));
}

Output:

group 1: This order was placed for QT
group 2: 3000
group 3: ! OK?

More info on Java Pattern here.

Finally, the capturing groups are delimited by round brackets, and provide a very useful way to use back-references (amongst other things), once your Pattern is matched to the input.

In Java 6 groups can only be referenced by their order (beware of nested groups and the subtlety of ordering).

In Java 7 it's much easier, as you can use named groups.

Answer from Mena on Stack Overflow
🌐
Oracle
docs.oracle.com › javase › tutorial › essential › regex › groups.html
Capturing Groups (The Java™ Tutorials > Essential Java Classes > Regular Expressions)
For example, the expression (\d\d) defines one capturing group matching two digits in a row, which can be recalled later in the expression via the backreference \1. To match any 2 digits, followed by the exact same two digits, you would use (\d\d)\1 as the regular expression: Enter your regex: (\d\d)\1 Enter input string to search: 1212 I found the text "1212" starting at index 0 and ending at index 4.
🌐
TutorialsPoint
tutorialspoint.com › home › javaregex › java regex capturing groups
Java Regex Capturing Groups
September 1, 2008 - Learn about capturing groups in Java Regex, including how to use parentheses for grouping and extracting substrings from matches.
Top answer
1 of 5
308

The issue you're having is with the type of quantifier. You're using a greedy quantifier in your first group (index 1 - index 0 represents the whole Pattern), which means it'll match as much as it can (and since it's any character, it'll match as many characters as there are in order to fulfill the condition for the next groups).

In short, your 1st group .* matches anything as long as the next group \\d+ can match something (in this case, the last digit).

As per the 3rd group, it will match anything after the last digit.

If you change it to a reluctant quantifier in your 1st group, you'll get the result I suppose you are expecting, that is, the 3000 part.

Note the question mark in the 1st group.

String line = "This order was placed for QT3000! OK?";
Pattern pattern = Pattern.compile("(.*?)(\\d+)(.*)");
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
    System.out.println("group 1: " + matcher.group(1));
    System.out.println("group 2: " + matcher.group(2));
    System.out.println("group 3: " + matcher.group(3));
}

Output:

group 1: This order was placed for QT
group 2: 3000
group 3: ! OK?

More info on Java Pattern here.

Finally, the capturing groups are delimited by round brackets, and provide a very useful way to use back-references (amongst other things), once your Pattern is matched to the input.

In Java 6 groups can only be referenced by their order (beware of nested groups and the subtlety of ordering).

In Java 7 it's much easier, as you can use named groups.

2 of 5
20

This is totally OK.

  1. The first group (m.group(0)) always captures the whole area that is covered by your regular expression. In this case, it's the whole string.
  2. Regular expressions are greedy by default, meaning that the first group captures as much as possible without violating the regex. The (.*)(\\d+) (the first part of your regex) covers the ...QT300 int the first group and the 0 in the second.
  3. You can quickly fix this by making the first group non-greedy: change (.*) to (.*?).

For more info on greedy vs. lazy, check this site.

🌐
Medium
medium.com › stackera › java-regex-part-6-group-and-subgroup-2985dc2d42d4
Java RegEx: Part 6 — Group and Subgroup | by Sera Ng. | Tech Training Space | Medium
October 18, 2020 - The main purpose of using groups and subgroups is that we can separate the input string into sections and extract those sections if they are matched with the defined pattern. In java regular expressions, every pattern can have groups. And groups ...
🌐
JDriven
jdriven.com › blog › 2020 › 04 › Java-Joy-Using-Named-Capturing-Groups-In-Regular-Expressions
Java Joy: Using Named Capturing Groups In Regular Expressions - JDriven Blog
April 20, 2020 - In Java we can define capturing groups in regular expression. We can refer to these groups (if found) by the index from the group as defined in the regular expression. Instead of relying on the index of the group we can give a capturing group a name and use that name to reference the group.
🌐
Baeldung
baeldung.com › home › java › java string › non-capturing regex groups in java
Non-Capturing Regex Groups in Java | Baeldung
January 8, 2024 - Non-capturing groups are important constructs within Java Regular Expressions. They create a sub-pattern that functions as a single unit but does not save the matched character sequence.
🌐
Java2s
java2s.com › Tutorials › Java › Java_Regular_Expression › 0070__Java_Regex_Groups.htm
Java Regular Expression Tutorial - Java Regex Groups
Java Regex Groups · Java Regex Find/Replace · « Previous · Next » · We can group multiple characters as a unit by parentheses. For example, (ab). Each group in a regular expression has a group number, which starts at 1. Method groupCount() from Matcher class returns the number of groups ...
🌐
Bennadel
bennadel.com › blog › 4286-playing-with-java-patterns-named-capture-groups-in-coldfusion.htm
Playing With Java Pattern's Named Capture Groups In ColdFusion
June 20, 2022 - In this case, we're attempting // to extract parts of an email address using NAMED CAPTURE GROUPS. pattern = "(?x)^ (?<user> [^+@]+ ) ( \+ (?<hash> [^@]+ ) )? @ (?<domain> .+ ) "; extractEmail( "jane.doe@example.com" ) extractEmail( "jane.doe+spam@example.com" ) extractEmail( "j.a.n.e.d.o.e@example.com" ) // ------------------------------------------------------------------------------- // // ------------------------------------------------------------------------------- // /** * I match the Java Regular Expression pattern against the given input and then output * the NAMED CAPTURE GROUPS. */
Find elsewhere
🌐
Coderanch
coderanch.com › t › 446647 › java › result-regex-groups
Getting more than one result from regex groups (Beginning Java forum at Coderanch)
So if you just want the groups counted from groupCount() you should start the for index at 1, not zero: ... But this is only part of the problem. The Regex you are using will only match one group in the String at a time, because you don't give it a pattern where multiple groups are captured.
🌐
Java Mex
javamex.com › tutorials › regular_expressions › capturing_groups.shtml
Java regular expressions: capturing groups
Tutorial on using capturing groups in Java regular expressions, allowing you to 'pull out' parts of the string that match particular sub-expressions.
🌐
Cronn
blog.cronn.de › en › java › 2023 › 07 › 14 › named-capturing-groups-in-jdk-20.html
cronn GmbH - Elevate your Regex: Named Capturing Groups in Java's JDK 20 API
It is a good practice to name multiple groups for better readability, like (?<groupName>.*). Let’s look at an example: @Test void matchDifferentTypesOfIds() { String text = """ Some text. Tax Id: 123. Some text. Some text, Court Id: 456, Stats Id: 789. """; var pattern = Pattern.compile("(?i)(?<type>\\w+ *Id)[: ]*?(?<id>\\d+)"); var matcher = pattern.matcher(text); // using "java.util.regex.MatchResult.group(int)" to extract capture List<IdEntry> idEntries = matcher.results() .map(m -> new IdEntry(m.group(1), m.group(2))) .toList(); assertThat(idEntries) .extracting(IdEntry::type, IdEntry::id) .containsExactly(tuple("Tax Id", "123"), tuple("Court Id", "456"), tuple("Stats Id", "789")); }
🌐
Kodejava
kodejava.org › how-do-i-use-capturing-groups-in-regex
How do I use capturing groups in regex? - Learn Java by Examples
Each pair of parentheses in a regular expression defines a separate capturing group in addition to the group that the whole expression defines. package org.kodejava.regex; import java.util.regex.Matcher; import java.util.regex.Pattern; public ...
🌐
Alvin Alexander
alvinalexander.com › blog › post › java › how-extract-multiple-groups-patterns-string-regex
Extract multiple groups from a Java String using Pattern and Matcher | alvinalexander.com
* @see http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html */ public class PatternMatcherGroupMultiple { public static void main(String[] args) { String stringToSearch = "Four score and seven years ago our fathers ..."; // specify that we want to search for two groups in the string Pattern p = Pattern.compile(" (\\S+or\\S+) .* (\\S+the\\S+).*"); Matcher m = p.matcher(stringToSearch); // if our pattern matches the string, we can try to extract our groups if (m.find()) { // get the two groups we were looking for String group1 = m.group(1); String group2 = m.group(2); // print the groups, with a wee bit of formatting System.out.format("'%s', '%s'\n", group1, group2); } } }
🌐
Microsoft Learn
learn.microsoft.com › en-us › dotnet › api › java.util.regex.matcher.group
Matcher.Group Method (Java.Util.Regex) | Microsoft Learn
For a matcher m with input sequence s, the expressions m.group() and s.substring(m.start(),&nbsp;m.end()) are equivalent. Note that some patterns, for example a*, match the empty string. This method will return the empty string when the pattern successfully matches the empty string in the input. Java documentation for java.util.regex.Matcher.group().
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › util › regex › Pattern.html
Pattern (Java Platform SE 8 )
October 20, 2025 - Groups beginning with (? are either ... or named-capturing group. This class is in conformance with Level 1 of Unicode Technical Standard #18: Unicode Regular Expression, plus RL2.1 Canonical Equivalents. Unicode escape sequences such as \u2014 in Java source code are processed ...
🌐
GeeksforGeeks
geeksforgeeks.org › java › matcher-group-method-in-java-with-examples
Matcher group() method in Java with Examples - GeeksforGeeks
November 26, 2018 - // Java code to illustrate end() method import java.util.regex.*; public class GFG { public static void main(String[] args) { // Get the regex to be checked String regex = "(G*G)"; // Create a pattern from regex Pattern pattern = Pattern.compile(regex); // Get the String to be matched String stringToBeMatched = "GFG FGF GFG"; // Create a matcher for the input String Matcher matcher = pattern .matcher(stringToBeMatched); // Get the current matcher state MatchResult result = matcher.toMatchResult(); System.out.println("Current Matcher: " + result); while (matcher.find()) { // Get the group matched using group() method System.out.println(matcher.group()); } } } ... Current Matcher: java.util.regex.Matcher[pattern=(G*G) region=0, 11 lastmatch=] G G G G G Reference: Oracle Doc
🌐
Mrhaki
blog.mrhaki.com › 2020 › 04 › java-joy-using-named-capturing-groups.html
Java Joy: Using Named Capturing Groups In Regular Expressions - Messages from mrhaki
April 9, 2020 - In Java we can define capturing groups in regular expression. We can refer to these groups (if found) by the index from the group as defined in the regular expression. Instead of relying on the index of the group we can give a capturing group ...
🌐
TutorialsPoint
tutorialspoint.com › home › javaregex › java regex matcher group
Java Regex Matcher Group
September 1, 2008 - The following example shows the usage of java.time.Matcher.group(int group) method. package com.tutorialspoint; import java.util.regex.Matcher; import java.util.regex.Pattern; public class MatcherDemo { private static String REGEX = "(a*b)(foo)"; private static String INPUT = "aabfooaabfooabfoob"; private static String REPLACE = "-"; public static void main(String[] args) { Pattern pattern = Pattern.compile(REGEX); // get a matcher object Matcher matcher = pattern.matcher(INPUT); if(matcher.find()) { //Prints the offset after the last character matched.
🌐
Educative
educative.io › answers › what-is-the-group-function-of-the-matcher-class-in-java
What is the group() function of the Matcher class in Java?
The group() function of the Java Matcher class is used to return the specific substring that matches the most recent match operation. The java.util.regex package contains the Matcher class, which compares texts to regular expressions.
Top answer
1 of 4
2

Your pattern doesn't match because it requires an open curly brace at the end, but your input doesn't have one.

Ignoring that small problem, the main problem is the little + after your capture group (.*)+. The plus requires one or more matches of .* and the group returned is the last match of the many. The term .* is greedy, so it consumes everything up to the bracket. The only way to match again is to consume nothing. So the last match of group 2 is blank.

To fix it, remove the + after group 2:

Pattern PATTERN = Pattern.compile("\\s*temp\\s+([A-Za-z]+)\\s*[(]\\s*(.*)[)]\\s*");

Note also how I removed other unnecessary characters from your regex, eg the single-character character classes - ie [\\s] is identical to \s. And \\s+\\s* is identical to just \\s+, because + is greedy.

I also removed the trailing curly bracket, which you can restore if your input data actually has it (your question showed input of "temp name(this is the data)", which has no trailing curly bracket).

2 of 4
1

Your regex should be this:

Pattern pattern = Pattern.compile("\\s*temp\\s+([A-Za-z]+)\\s*[(]\\s*(.*)[)]\\s*");

You had (.*)+ which means one or more matches of .*. This results in nothing being captured.

Testing:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Example {

    public static void main(String[] args) {

        Pattern pattern = Pattern.compile("\\s*temp\\s+([A-Za-z]+)\\s*[(]\\s*(.*)[)]\\s*");

        Matcher m = pattern.matcher("temp name(this is the data)");
        if(m.matches()) {
            System.out.println(m.group(1));
            System.out.println(m.group(2));
        }
    }
}

Output:

name
this is the data