Java Matcher.results Method
Last modified: April 20, 2025
The Matcher.results
method was introduced in Java 9 as part of
the java.util.regex.Matcher
class. It returns a stream of match
results for a regular expression pattern. This method provides a modern,
functional approach to regex matching.
Unlike traditional find
loops, results
enables
stream processing of matches. Each match is represented as a
MatchResult
object. The method is particularly useful for
processing multiple matches in a declarative style.
Matcher.results Overview
The results
method scans the input sequence and returns all
matches found. It produces a stream of MatchResult
objects. Each
object contains information about a single match, including captured groups.
The method is non-terminal, meaning it doesn't consume the matcher. You can call it multiple times on the same matcher. However, the matcher's state must not be modified between calls.
Basic Usage of Matcher.results()
This example demonstrates the simplest use case of results
. We
find all occurrences of a word in a string and print them. The stream
processing makes the code concise and readable.
package com.zetcode; import java.util.regex.Pattern; import java.util.regex.Matcher; public class BasicResultsExample { public static void main(String[] args) { String text = "The quick brown fox jumps over the lazy dog"; Pattern pattern = Pattern.compile("\\b\\w{4}\\b"); // 4-letter words Matcher matcher = pattern.matcher(text); matcher.results() .forEach(mr -> System.out.println("Found: " + mr.group())); } }
In this example, we compile a pattern to match 4-letter words. The
results
method returns a stream of matches. We use
forEach
to print each match. The group
method of
MatchResult
returns the matched text.
Counting Matches with results
The results
method integrates well with stream operations. This
example shows how to count matches using the stream API. This approach is more
concise than traditional iteration.
package com.zetcode; import java.util.regex.Pattern; import java.util.regex.Matcher; public class CountMatchesExample { public static void main(String[] args) { String log = "2023-01-01 INFO Start\n2023-01-01 DEBUG Process\n" + "2023-01-02 ERROR Failed\n2023-01-02 INFO Complete"; Pattern pattern = Pattern.compile("ERROR"); Matcher matcher = pattern.matcher(log); long errorCount = matcher.results().count(); System.out.println("Number of ERROR entries: " + errorCount); } }
Here we search for "ERROR" entries in a log string. The results
method provides a stream that we can directly count with count
.
This eliminates the need for manual iteration and counter variables.
Extracting Group Information
MatchResult
objects provide access to captured groups. This example
shows how to extract specific group information from each match. We parse dates
from a string and format them differently.
package com.zetcode; import java.util.regex.Pattern; import java.util.regex.Matcher; public class GroupExtractionExample { public static void main(String[] args) { String dates = "2023-05-15, 2024-01-20, 2025-11-30"; Pattern pattern = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})"); Matcher matcher = pattern.matcher(dates); matcher.results() .map(mr -> String.format("Day: %s, Month: %s, Year: %s", mr.group(3), mr.group(2), mr.group(1))) .forEach(System.out::println); } }
This code matches date strings and extracts their components. The pattern
captures year, month, and day in separate groups. We use map
to
reformat each match, accessing groups by their indices. The result is a
stream of reformatted date strings.
Filtering and Processing Matches
The stream API allows sophisticated processing of matches. This example filters matches based on group content and performs calculations. We find and sum specific numeric values in a string.
package com.zetcode; import java.util.regex.Pattern; import java.util.regex.Matcher; public class FilterAndSumExample { public static void main(String[] args) { String data = "A=5, B=3, C=8, A=2, B=7, C=1"; Pattern pattern = Pattern.compile("([A-C])=(\\d+)"); Matcher matcher = pattern.matcher(data); int sumA = matcher.results() .filter(mr -> "A".equals(mr.group(1))) .mapToInt(mr -> Integer.parseInt(mr.group(2))) .sum(); System.out.println("Sum of A values: " + sumA); } }
Here we extract key-value pairs from a string. We filter for only "A" values,
convert them to integers, and sum them. The combination of results
with stream operations creates a powerful data processing pipeline.
Named Capture Groups with results
Named capture groups make patterns more readable. This example demonstrates how
to use named groups with results
. We parse user information from
a formatted string.
package com.zetcode; import java.util.regex.Pattern; import java.util.regex.Matcher; public class NamedGroupsExample { public static void main(String[] args) { String users = "user:john age:30; user:jane age:25"; Pattern pattern = Pattern.compile( "user:(?<name>\\w+)\\s+age:(?<age>\\d+)"); Matcher matcher = pattern.matcher(users); matcher.results() .forEach(mr -> System.out.printf( "User %s is %s years old%n", mr.group("name"), mr.group("age"))); } }
The pattern defines named groups "name" and "age". We access these groups by
name in the forEach
operation. Named groups make the code more
maintainable by eliminating magic numbers for group indices.
Parallel Processing of Matches
The stream from results
can be processed in parallel. This
example shows how to leverage multi-core processors for regex matching. We
process a large text with parallel stream operations.
package com.zetcode; import java.util.regex.Pattern; import java.util.regex.Matcher; public class ParallelProcessingExample { public static void main(String[] args) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < 100; i++) { sb.append("item").append(i).append(" "); } String largeText = sb.toString(); Pattern pattern = Pattern.compile("item\\d+"); Matcher matcher = pattern.matcher(largeText); long count = matcher.results() .parallel() .count(); System.out.println("Total items found: " + count); } }
We generate a large string with many "itemN" patterns. The parallel
call enables parallel processing of matches. This can significantly improve
performance for large inputs, though ordering is not guaranteed.
Combining results() with Other Stream Operations
results
integrates with the full Java stream API. This example
shows advanced stream operations like collecting to a map. We build a frequency
map of words in a text.
package com.zetcode; import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.stream.Collectors; import java.util.Map; public class StreamOperationsExample { public static void main(String[] args) { String text = "apple banana apple cherry banana apple"; Pattern pattern = Pattern.compile("\\b\\w+\\b"); Matcher matcher = pattern.matcher(text); Map<String, Long> wordCounts = matcher.results() .collect(Collectors.groupingBy( mr -> mr.group().toLowerCase(), Collectors.counting())); System.out.println("Word counts: " + wordCounts); } }
This code counts occurrences of each word in a string. The results
stream is collected into a map where keys are words and values are counts. This
demonstrates how regex matching can feed into complex data processing pipelines.
Source
Java Matcher.results() Documentation
The Matcher.results
method provides a modern approach to regex
matching in Java. By returning a stream of matches, it enables functional-style
processing that is often more concise and expressive than traditional iteration.
Author
List all Java tutorials.