Pattern.compile()必须先调用,因为Matcher依赖Pattern创建且不可独立实例化;matches()要求全字符串匹配,lookingAt()从开头匹配不需结尾,find()查找任意子串;group()等操作需先成功匹配,reset()可重置输入但不重编译;Pattern线程安全可复用,Matcher线程不安全须每次新建。
Java 的 Pattern 是不可变的正则编译结果,Matcher 不能独立存在——它必须由 Pattern 实例通过 matcher() 方法创建。直接 new Matcher() 会编译失败。
常见错误是试图复用 Matcher 对象处理不同字符串,结果匹配行为异常(比如仍沿用上次的输入或状态)。正确做法是每次对新字符串调用 pattern.matcher(input) 获取新 Matcher。
Pattern 编译一次可重复使用,适合固定正则(如邮箱校验)Pattern.compile() 而不缓存会拖慢性能,尤其在循环中PatternSyntaxException
这三个方法都触发匹配,但语义完全不同,选错会导致逻辑漏洞。
matches():要求整个输入字符串**完全匹配**正则(隐式加了 ^ 和 $),例如 "\\d+".matches("123abc") 返回 false
lookingAt():从字符串**开头开始匹配**,不要求到结尾,类似 ^ 但不带 $,"\\d+".lookingAt("123abc") 返回 true
find():在字符串中**查找任意位置的子串匹配**,可多次调用跳到下一个匹配项,适合提取多个结果典型误用:用 matches() 去验证手机号是否“包含”某段数字,结果永远 false——该用 find()。
捕获组(括号)提取内容依赖 Matcher 的状态,而这个状态只在 find() 或 matches() 成功后才有效。没调用就直接 group(1) 会抛 IllegalStateException。
group(0) 是整个匹配串,group(1) 是第一个括号内的内容groupCount() 返回正则中捕获组数量(不包括 group(0)),不是匹配到的组数reset() 可重置 Matcher 到新字符串,避免反复创建对象;但不会清空已编译的 Pattern
Pattern p = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");
Matcher m = p.matcher("2025-04-01");
if (m.find()) {
System.out.println(m.group(1)); // "2025"
System.out.println(m.group(2)); // "04"
}
m.reset("2025-12-25"); // 复用 matcher
if (m.find()) {
System.out.println(m.group(1)); // "2025"
}
多个线程共用同一个 Matcher 实例会导致匹配结果错乱甚至 ConcurrentModificationException;而 Pattern 是不可变对象,可被所有线程安全共享。
Pattern 定义为 private static final 字段Matc
her:pattern.matcher(input)
Matcher,除非明确限定单线程生命周期容易被忽略的是:即使只读取 group(),只要 Matcher 被多线程并发调用过 find(),状态就可能污染。安全边界很窄,宁可每次都 new。