183. Java 模式匹配

37 阅读4分钟

183. Java 模式匹配

Java 中,模式匹配(Pattern Matching) 是一项不断演进的新特性,它正在逐步引入 Java 语言规范中。你可能会在不同的上下文中看到“模式匹配”这个词,比如:

  • 正则表达式(Regex):主要用于字符串的分析与匹配。
  • instanceof 模式匹配:用于对象类型判断和自动类型转换。
  • 未来甚至会用于 switch 表达式中的模式匹配JEP 441)。

🔍 Java 中的正则表达式模式匹配

如果你最先联想到的是正则表达式,那么很好,这就是我们从“字符串分析”角度开始了解模式匹配的入口。

🎭 什么是正则表达式?

正则表达式(Regular Expression)是一种用于匹配字符串模式的工具,比如查找一个单词是否在一段文本中出现过。


✅ 示例:查找单词 "flame" 在文本中出现的位置

import java.util.regex.*;

public class PatternExample {
    public static void main(String[] args) {
        String sonnet = "From fairest creatures we desire increase,\n" +
                "That thereby beauty's rose might never die,\n" +
                "But as the riper should by time decease\n" +
                "His tender heir might bear his memory:\n" +
                "But thou, contracted to thine own bright eyes,\n" +
                "Feed'st thy light's flame with self-substantial fuel,\n" +
                "Making a famine where abundance lies,\n" +
                "Thyself thy foe, to thy sweet self too cruel.\n" +
                "Thou that art now the world's fresh ornament,\n" +
                "And only herald to the gaudy spring,\n" +
                "Within thine own bud buriest thy content,\n" +
                "And, tender churl, mak'st waste in niggardly.\n" +
                "Pity the world, or else this glutton be,\n" +
                "To eat the world's due, by the grave and thee.";

        Pattern pattern = Pattern.compile("\\bflame\\b");
        Matcher matcher = pattern.matcher(sonnet);

        while (matcher.find()) {
            String match = matcher.group();      // 匹配到的内容
            int start = matcher.start();         // 起始位置
            int end = matcher.end();             // 结束位置
            System.out.println(match + " " + start + " " + end);
        }
    }
}

输出结果:

flame 233 238

这表示:

  • 在这段十四行诗中,单词 flame 出现在下标 233238 的位置。
  • \\b 是正则表达式中的“单词边界”,确保匹配的是整个单词 flame,而不是像 “inflamed” 这样的子串。

🧠 模式匹配的三个核心元素

在使用正则表达式时,有三个基本组成部分需要理解:

概念含义说明示例
Matched Target要匹配的目标文本sonnet(整首十四行诗)
Pattern用于匹配的规则或格式\\bflame\\b(匹配整个单词 flame
Match Result匹配成功后返回的结果,包括匹配内容及位置"flame" + start/end 索引

这些概念适用于正则表达式,也适用于未来更高级的“结构模式匹配”功能。


🧪 拓展示例:匹配多个单词

你可以很容易地扩展模式来查找多个关键词。例如,如果我们想匹配所有以 th 开头的单词:

Pattern pattern = Pattern.compile("\\bth\\w*\\b");
Matcher matcher = pattern.matcher(sonnet);

这将匹配 like thou, thy, thine, that 等等。


📘 小贴士:正则表达式是模式匹配的一个子集

虽然我们现在学习的是通过 java.util.regex.PatternMatcher 类对字符串进行分析,但要知道:

🧩 “正则表达式模式匹配” 是 Java 模式匹配能力的基础,也是更复杂结构模式匹配的起点。


📍 更多高级模式匹配

如果你对 Java 中类型结构上的模式匹配(如 instanceof 改进、switch 中的类型判断)感兴趣,可以深入了解 JEP 394, JEP 433, JEP 441 等。

JEP 394 、 JEP 433 、 JEP 441 是 Java 不同版本中提出的增强提案(Java Enhancement Proposal),分别对应 Java 16 、 Java 20 和 Java 21 的特定功能改进。

JEP 394:模式匹配的 instanceof

在 Java 16 中,JEP 394引入了模式匹配的 instanceof 运算符,支持在类型检查时使用模式匹配语法,例如 if 语句和 switch 表达式中可直接使用模式匹配。 ‌

JEP 433:Switch 的模式匹配

Java 20 通过JEP 433进一步扩展了 switch 表达式的模式匹配功能,新增类型标签、守卫标签等特性,优化了语法结构并增强了灵活性。 ‌

JEP 441:Switch 的模式匹配

Java 21 的JEP 441将模式匹配功能正式引入 switch 表达式,支持枚举常量作为值、null标签等高级用法,并优化了语法结构。

例如:

if (obj instanceof String s) {
    System.out.println("字符串长度:" + s.length());
}

✅ 小结

模式匹配类型使用场景Java 示例类
正则表达式匹配字符串查找、替换Pattern, Matcher
instanceof 模式匹配类型判断与转换instanceof, 模式变量
Switch 模式匹配分支结构优化switch (obj)