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
Top answer
1 of 5
309

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.

🌐
TutorialsPoint
tutorialspoint.com › javaregex › javaregex_capturing_groups.htm
Java Regex - Capturing Groups
Capturing groups are a way to treat multiple characters as a single unit. They are created by placing the characters to be grouped inside a set of parentheses. For example, the regular expression (dog) creates a single group containing the letters
🌐
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. */
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › util › regex › Pattern.html
Pattern (Java Platform SE 8 )
July 21, 2026 - 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 ...
🌐
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 ...
🌐
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.
🌐
Rexegg
rexegg.com › regex-capture.php
Regex Capture Groups and Back-References
If there is no Group 10, however, Java translates \10 as a back-reference to Group 1, followed by a literal 0; Python understands it as a back-reference to Group 10 (which will fail); and C#, PCRE, JavaScript, Perl and Ruby understand it as an instruction to match "the backspace character" ...
Find elsewhere
🌐
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 - Matcher issueMatcher = issuePattern.matcher("PRJ-CLD-42"); assert issueMatcher.matches(); // We can use capturing group names to get group. assert issueMatcher.group("project").equals("PRJ"); assert issueMatcher.group("org").equals("CLD"); assert issueMatcher.group("num").equals("42"); // Using separator / also matches. assert issuePattern.matcher("EUR/ACC/91").matches(); // But we cannot mix - and /. assert !issuePattern.matcher("EUR-ACC/91").matches(); // Backreferences to the capturing groups can be used by // their names, using the syntax ${name}. assert issueMatcher.replaceAll("${project} ${num} in ${org}.").equals("PRJ 42 in CLD."); } } Written with Java 14.
🌐
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.
🌐
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.
🌐
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 ...
🌐
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
July 14, 2023 - 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")); }
🌐
TutorialsPoint
tutorialspoint.com › article › named-captured-groups-java-regular-expressions
Named captured groups Java regular expressions
March 11, 2026 - Java started supporting captured groups since SE7. import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ReplaceAll{ public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("Enter input text: "); String input = sc.nextLine(); String regex = "(?<globalCode>[\d]{2})-(?<nationalCode>[\d]{5})-(?<number>[\d]{6})"; //Creating a pattern object Pattern pattern = Pattern.compile(regex); //Matching the compiled pattern in the String Matcher matcher = pattern.matcher(input); while (matcher.find()) { System.out.println("Global code: "+matcher.group("globalCode")); System.out.println("National code: "+matcher.group("nationalCode")); System.out.println("Phone number: "+matcher.group("number")); } } } Enter input text: 91-08955-224558 Global code: 91 National code: 08955 Phone number: 224558 ·
🌐
W3Schools
w3schools.com › java › java_inner_classes.asp
Java Inner Class (Nested Class)
Nest a class inside another class in Java to group related types together.
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Regular_expressions › Capturing_group
Capturing group: (...) - JavaScript | MDN
A pattern consisting of anything you may use in a regex literal, including a disjunction. A capturing group acts like the grouping operator in JavaScript expressions, allowing you to use a subpattern as a single atom.
🌐
Starship
starship.rs › config
Starship: Cross-Shell Prompt
August 10, 2026 - Note that all regular expression are anchored with ^<pattern>$ and so must match the whole string. The *_pattern regular expressions may contain capture groups, which can be referenced in the corresponding alias via $name and $N (see example below and the rust Regex::replace() documentation).
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › util › regex › Matcher.html
Matcher (Java Platform SE 8 )
July 21, 2026 - The explicit state of a matcher includes the start and end indices of the most recent successful match. It also includes the start and end indices of the input subsequence captured by each capturing group in the pattern as well as a total count of such subsequences.
🌐
Microsoft Learn
learn.microsoft.com › en-us › dotnet › standard › base-types › grouping-constructs-in-regular-expressions
Grouping Constructs in Regular Expressions - .NET | Microsoft Learn
You can use grouping constructs to do the following: Match a subexpression that's repeated in the input string. Apply a quantifier to a subexpression that has multiple regular expression language elements.
🌐
Vogella
vogella.com › tutorials › JavaRegularExpressions › article.html
Regular expressions in Java - Tutorial
This chapter serves as a reference for the different regex elements. The following meta characters have a predefined meaning and make certain common patterns easier to use. For example, you can use \d as simplified definition for [0..9]. A quantifier defines how often an element can occur. The symbols ?, *, + and {} are quantifiers. You can group parts of your regular expression.