Java Pattern 与 Matcher
·
一、Pattern & Matcher 核心介绍📌
java.util.regex.Pattern与Matcher是 Java 正则表达式核心 API:
- Pattern:正则表达式编译模板,负责将正则字符串编译成正则模式,无法直接实例化,通过
Pattern.compile(正则)静态方法创建。 - Matcher:匹配器对象,由
pattern.matcher(目标字符串)生成,提供分组查找、位置匹配、提取子串等方法,是真正执行正则匹配的对象。
常用方法:
find():从当前位置向后查找匹配内容,找到返回 true;group(n):获取第 n 分组匹配到的子串(group()等价group(0),取整体匹配内容);start()/end():返回匹配子串起始、结束下标。
二、需求说明
原始账单文本:
plaintext
从3到8匹配的子序列:76.89
从12到17匹配的子序列:67.38
从21到26匹配的子序列:12.68
通信总费用:156.95元
三地的平均气温:[-1.0, 15.5, -18.0]
三地的平均气温(升序):[-18.0, -1.0, 15.5]
业务需求:
- 提取所有小数数字,计算账单金额总和;
- 提取括号内气温数值,计算三地平均气温、排序。
正则设计
- 匹配小数正则:
-?\\d+\\.\\d+(-?可选负号、整数位、小数点、小数位)
三、完整实现代码
java
运行
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PatternMatcherDemo {
public static void main(String[] args) {
// 原始文本
String content = "从3到8匹配的子序列:76.89\n" +
"从12到17匹配的子序列:67.38\n" +
"从21到26匹配的子序列:12.68\n" +
"通信总费用:156.95元\n" +
"三地的平均气温:[-1.0, 15.5, -18.0]\n" +
"三地的平均气温(升序):[-18.0, -1.0, 15.5]";
// 1.编译正则模板:匹配正负小数
String reg = "-?\\d+\\.\\d+";
Pattern pattern = Pattern.compile(reg);
Matcher matcher = pattern.matcher(content);
List<Double> allNum = new ArrayList<>();
List<Double> tempList = new ArrayList<>();
// 2.循环查找所有匹配数字
while (matcher.find()) {
String numStr = matcher.group();
double num = Double.parseDouble(numStr);
allNum.add(num);
System.out.println("匹配数值:"+numStr+" 匹配区间:["+matcher.start()+"~"+matcher.end()+"]");
}
// 拆分:账单费用(前4个)、气温(后3个)
List<Double> costList = allNum.subList(0,4);
tempList.addAll(allNum.subList(4,7));
// 账单费用求和
double totalCost = 0;
for(Double cost:costList){
totalCost += cost;
}
System.out.println("\n===账单统计===");
System.out.println("各项费用:"+costList);
System.out.println("通信总费用合计:"+totalCost+"元");
// 气温计算:平均值+升序排序
double avgTemp = 0;
for(Double t:tempList) avgTemp += t;
avgTemp /= tempList.size();
Collections.sort(tempList);
System.out.println("\n===气温统计===");
System.out.println("原始气温数组:"+allNum.subList(4,7));
System.out.println("气温升序数组:"+tempList);
System.out.println("三地平均气温:"+avgTemp);
}
}
四、运行结果
plaintext
匹配数值:76.89 匹配区间:[20~25]
匹配数值:67.38 匹配区间:[45~50]
匹配数值:12.68 匹配区间:[70~75]
匹配数值:156.95 匹配区间:[87~93]
匹配数值:-1.0 匹配区间:[111~115]
匹配数值:15.5 匹配区间:[117~121]
匹配数值:-18.0 匹配区间:[124~129]
===账单统计===
各项费用:[76.89, 67.38, 12.68, 156.95]
通信总费用合计:313.9元
===气温统计===
原始气温数组:[-1.0, 15.5, -18.0]
气温升序数组:[-18.0, -1.0, 15.5]
三地平均气温:-1.1666666666666667
五、核心知识点解析💡
1.Pattern 编译优化
Pattern.compile()编译正则开销大,频繁使用的正则建议全局静态常量,避免重复编译:
java
运行
private static final Pattern NUM_PATTERN = Pattern.compile("-?\\d+\\.\\d+");
2.Matcher 三个关键方法
表格
| 方法 | 作用 |
|---|---|
find() |
游标向后搜索,每次找到一个匹配就暂停,下次继续向后 |
group() |
返回本次匹配到的完整字符串 |
start()/end() |
获取当前匹配内容在原字符串中的起始、结束索引 |
3. 正则细节说明
-?:负号可选,兼容负数气温-18.0;\\d+:小数点前整数部分(1 个及以上数字);\\.:转义小数点(.在正则代表任意字符,必须转义);\\d+:小数点后小数位。
六、拓展场景
- 分组提取:如需单独提取括号内容,可改用分组正则
\\[((-?\\d+\\.\\d+,?\\s*)+)\\],用group(1)取出括号内全部气温字符串; - 全局忽略大小写:编译时加参数
Pattern.CASE_INSENSITIVE:Pattern.compile(reg,Pattern.CASE_INSENSITIVE); - 多行匹配:
Pattern.DOTALL让.匹配换行符。
更多推荐

所有评论(0)