pattern负责编译正则规则,线程安全可复用;matcher绑定pattern与文本执行匹配,非线程安全需每次创建或重置;二者协作实现查找、提取、替换等操作。

Pattern 和 Matcher 是 Java 中处理正则表达式的两个核心类,分工明确:Pattern 负责编译规则,Matcher 负责执行匹配。掌握它们的协作逻辑,比死记语法更重要。
Pattern:正则规则的“编译器”
Pattern 对象代表一个已编译的正则表达式,它不操作文本,只负责把字符串形式的正则(如 "\d+\.?\d*")转换成高效可复用的内部状态机。这个过程有开销,所以通常只做一次,反复使用。
- 用 Pattern.compile(regex) 创建,推荐加 static final 修饰以复用
- 它是线程安全的,多个线程可共享同一个 Pattern 实例
- 支持传入标志位,比如 Pattern.CASE_INSENSITIVE 忽略大小写
- 直接调用 Pattern.matches(regex, input) 是快捷方式,但底层仍会临时编译 Pattern,适合单次简单校验
Matcher:真正干活的“匹配引擎”
Matcher 绑定一个 Pattern 和一段待处理文本,是实际执行查找、提取、替换操作的对象。它不是线程安全的,每次匹配都应创建新实例或重置。
- 通过 pattern.matcher(input) 获取,input 可以是 String、StringBuilder 等 CharSequence 类型
- find() 最常用:从当前位置向后扫描,找到下一个匹配子串,返回 true 并定位;循环调用可提取全部匹配项
- matches() 要求整个输入字符串完全符合正则,常用于格式验证(如邮箱、手机号)
- lookingAt() 只匹配字符串开头,不要求全覆盖,适合前缀判断
- 匹配成功后,group() 返回完整匹配内容,group(1) 等可获取括号定义的捕获组
典型实战:从文本中稳定提取数字
比如处理日志行 "CPU usage: 72.5%, Memory: 3456MB",目标是分别拿到浮点数和整数。
- 正则可写为 "\d+\.\d+|\d+":先尝试匹配带小数点的数字,再匹配纯整数(注意顺序,避免整数部分被优先截断)
- 更稳妥的方式是用分组:"(\d+\.\d+)|(\d+)",然后在循环中检查 group(1) 或 group(2) 哪个非 null
- 代码中别忘了异常处理——Double.parseDouble() 遇到空字符串或非法格式会抛 NumberFormatException
- 如果只需第一个匹配,用 if (matcher.find()) 即可;要遍历全部,必须用 while (matcher.find())
常见陷阱与优化建议
初学者容易卡在细节上,这些点直接影响结果可靠性:
- 正则中的 \d 在某些 Unicode 环境下可能匹配非 ASCII 数字,如需严格限定 0–9,改用 [0-9]
- 匹配小数时 \d+\.?\d* 会错误匹配 "123." 或 ".",应改为 \d+\.\d+|\d+ 或更严谨的 -?\d+(\.\d+)?
- 大量重复匹配场景下,避免每次 new Pattern.compile(...),把 Pattern 提取为常量
- Matcher 对象不能跨文本复用,但可通过 matcher.reset(newInput) 快速切换目标字符串,比新建对象轻量











