ZetCode

Java MatchResult 接口

上次修改时间:2025 年 4 月 20 日

java.util.regex.MatchResult 接口表示匹配操作的结果。 它提供了查询正则表达式匹配结果的方法。 MatchResult 通常从 Matcher 实例获得。

该接口包含获取有关组、匹配的起始和结束位置的信息的方法。 它允许访问匹配结果,而无需修改 Matcher 状态。 MatchResult 由 Matcher 实现,并在流结果中使用。

MatchResult 接口概述

MatchResult 提供了检查模式匹配操作结果的方法。 该接口由 Matcher 实现,并在处理匹配结果时使用。 它提供对匹配信息的只读访问。

关键方法包括用于访问匹配详细信息的 groupstartend。 该接口支持编号和命名捕获组。 MatchResult 对象是不可变的。

MatchResult 的基本用法

使用 MatchResult 的最简单方法是通过 Matcher 的匹配操作。 成功匹配后,Matcher 本身实现 MatchResult。 此示例显示了基本匹配信息检索。

BasicMatchResult.java
package com.zetcode;

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

public class BasicMatchResult {

    public static void main(String[] args) {
        String input = "The quick brown fox jumps over the lazy dog";
        Pattern pattern = Pattern.compile("(\\w{5})");
        Matcher matcher = pattern.matcher(input);
        
        while (matcher.find()) {
            System.out.println("Match: " + matcher.group());
            System.out.println("Start index: " + matcher.start());
            System.out.println("End index: " + matcher.end());
            System.out.println("Group count: " + matcher.groupCount());
            System.out.println();
        }
    }
}

此示例查找字符串中所有 5 个字母的单词。 对于每个匹配项,它会打印匹配的文本、起始和结束位置以及组计数。 在每次成功的匹配操作后,Matcher 对象充当 MatchResult。

find 方法在输入字符串中前进。 每次匹配后,我们可以通过 MatchResult 接口方法访问匹配详细信息。

使用组

MatchResult 提供对正则表达式中捕获组的访问。 组从 1 开始编号,组 0 表示整个匹配项。 此示例演示了组访问。

GroupMatchResult.java
package com.zetcode;

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

public class GroupMatchResult {

    public static void main(String[] args) {
        String input = "John Doe, age 30; Jane Smith, age 25";
        Pattern pattern = Pattern.compile("(\\w+) (\\w+), age (\\d+)");
        Matcher matcher = pattern.matcher(input);
        
        while (matcher.find()) {
            System.out.println("Full match: " + matcher.group(0));
            System.out.println("First name: " + matcher.group(1));
            System.out.println("Last name: " + matcher.group(2));
            System.out.println("Age: " + matcher.group(3));
            System.out.println();
        }
    }
}

此示例从格式化的字符串中提取名字、姓氏和年龄。 每个捕获组都按其索引访问。 组 0 包含整个匹配项,而组 1-3 包含捕获的子字符串。

组索引对应于正则表达式中左括号的顺序。 这允许结构化地提取匹配的内容。

命名组访问

Java 7 在正则表达式中引入了命名捕获组。 MatchResult 提供了按名称访问组的方法。 这使得模式更具可读性和可维护性。

NamedGroupMatchResult.java
package com.zetcode;

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

public class NamedGroupMatchResult {

    public static void main(String[] args) {
        String input = "Date: 2023-05-15, Time: 14:30";
        Pattern pattern = Pattern.compile(
            "Date: (?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2}), " +
            "Time: (?<hour>\\d{2}):(?<minute>\\d{2})");
        Matcher matcher = pattern.matcher(input);
        
        if (matcher.find()) {
            System.out.println("Year: " + matcher.group("year"));
            System.out.println("Month: " + matcher.group("month"));
            System.out.println("Day: " + matcher.group("day"));
            System.out.println("Hour: " + matcher.group("hour"));
            System.out.println("Minute: " + matcher.group("minute"));
        }
    }
}

此示例演示了命名组访问。 该模式使用描述性名称(如“year”和“month”)定义组。 group 方法接受这些名称以检索匹配的内容。

命名组提高了代码可读性,并使模式更易于维护。 它们在具有多个组的复杂正则表达式中尤其有用。

匹配位置信息

MatchResult 提供了获取匹配和组的起始和结束位置的方法。 这些位置对于子字符串操作或突出显示文本中的匹配项非常有用。 此示例显示了位置信息的使用。

PositionMatchResult.java
package com.zetcode;

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

public class PositionMatchResult {

    public static void main(String[] args) {
        String input = "The rain in Spain falls mainly on the plain";
        Pattern pattern = Pattern.compile("\\b\\w{4}\\b");
        Matcher matcher = pattern.matcher(input);
        
        while (matcher.find()) {
            System.out.println("Word: " + matcher.group());
            System.out.println("Starts at: " + matcher.start());
            System.out.println("Ends at: " + matcher.end());
            System.out.println("Substring: '" + 
                input.substring(matcher.start(), matcher.end()) + "'");
            System.out.println();
        }
    }
}

此示例查找字符串中所有 4 个字母的单词,并打印它们的位置。 startend 方法返回匹配项在输入字符串中的索引。 这些可以与子字符串操作一起使用。

位置信息从零开始,结束索引是独占的。 这与 Java 的标准子字符串行为相匹配。

流式处理匹配结果

Java 9 在 Matcher 中引入了 results 方法,该方法返回 MatchResult 对象的流。 这支持以函数式风格处理输入字符串中的所有匹配项。

StreamMatchResult.java
package com.zetcode;

import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class StreamMatchResult {

    public static void main(String[] args) {
        String input = "Apple: 1.25, Orange: 0.99, Banana: 0.50";
        Pattern pattern = Pattern.compile("(\\w+): (\\d+\\.\\d{2})");
        
        String formatted = pattern.matcher(input)
            .results()
            .map(mr -> mr.group(1) + " costs $" + mr.group(2))
            .collect(Collectors.joining("\n"));
            
        System.out.println(formatted);
    }
}

此示例使用 MatchResult 流处理产品价格信息。 results 方法生成所有匹配项的流。 处理每个 MatchResult 以创建格式化的字符串。

使用 MatchResult 进行流处理简洁而富有表现力。 它避免了显式循环,并且可以很好地与 Java 的函数式编程特性一起使用。

多组访问

MatchResult 允许一次访问匹配中的所有组。 当您需要系统地处理所有捕获的组时,这非常有用。 此示例显示了批量组访问。

MultipleGroupMatchResult.java
package com.zetcode;

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

public class MultipleGroupMatchResult {

    public static void main(String[] args) {
        String input = "RGB(255,128,64) HEX(#FF8040)";
        Pattern pattern = Pattern.compile(
            "(RGB|HEX)\\(([^)]+)\\)");
        Matcher matcher = pattern.matcher(input);
        
        while (matcher.find()) {
            System.out.println("Color format: " + matcher.group(1));
            System.out.println("Values:");
            
            for (int i = 2; i <=  matcher.groupCount(); i++) {
                String[] components = matcher.group(i).split(",");
                for (String component : components) {
                    System.out.println("  - " + component);
                }
            }
            System.out.println();
        }
    }
}

此示例处理不同格式的颜色值。 它演示了如何在匹配中访问多个组。 该代码系统地处理主要格式标识符之后的所有捕获组。

组计数有助于确定要处理的组数。 这种方法适用于具有可变数量的捕获组的模式。

MatchResult 中的异常处理

使用 MatchResult 时,务必处理可能不存在组的情况。 此示例演示了访问匹配结果时的正确错误处理。

ExceptionHandlingMatchResult.java
package com.zetcode;

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

public class ExceptionHandlingMatchResult {

    public static void main(String[] args) {
        String[] inputs = {
            "Name: John, Age: 30",
            "Invalid string",
            "Name: Jane, Age: 25, Email: jane@example.com"
        };
        
        Pattern pattern = Pattern.compile(
            "Name: (?<name>\\w+), Age: (?<age>\\d+)(?:, Email: (?<email>[^ ]+))?");
            
        for (String input : inputs) {
            Matcher matcher = pattern.matcher(input);
            
            if (matcher.find()) {
                try {
                    System.out.println("Name: " + matcher.group("name"));
                    System.out.println("Age: " + matcher.group("age"));
                    
                    String email = matcher.group("email");
                    System.out.println("Email: " + 
                        (email != null ? email : "not provided"));
                } catch (IllegalStateException e) {
                    System.out.println("No match found in: " + input);
                } catch (IllegalArgumentException e) {
                    System.out.println("Invalid group name in: " + input);
                }
            } else {
                System.out.println("No match found in: " + input);
            }
            System.out.println();
        }
    }
}

此示例显示了使用 MatchResult 时的健壮的错误处理。 它在访问组之前检查匹配项,并正确处理可选组。 该代码演示了捕获 IllegalStateException 和 IllegalArgumentException。

正确的错误处理可确保应用程序在处理意外的输入格式时不会崩溃。 它还提供有关匹配失败的有意义的反馈。

来源

Java MatchResult 接口文档

在本文中,我们介绍了 Java MatchResult 接口的基本方法和功能。 了解这些概念对于在 Java 应用程序中使用正则表达式匹配结果至关重要。

作者

我叫 Jan Bodnar,是一名敬业的程序员,在该领域拥有多年的经验。 我于 2007 年开始撰写编程文章,此后撰写了超过 1,400 篇文章和八本电子书。 凭借超过八年的教学经验,我致力于分享我的知识并帮助他人掌握编程概念。

列出所有Java教程