Java 正则表达式核心用法与实战案例详解

许南星
许南星
发布时间:2026-10-15 | 2人浏览过
原创

Java 1.4 引入的 java.util.regex 包是处理文本匹配、搜索和提取的强大工具。文章深入解析了 Pattern(编译模式)和 Matcher(状态匹配机)的核心方法,并通过覆盖基础匹配、字符类限定、多条件或逻辑、字符串分割及复杂替换的丰富实例,展示如何精准控制文本处理流程。

核心类库概述:Pattern 与 Matcher

java.util.regex 主要由两个类组成:Pattern 和 Matcher。Pattern 是将正则表达式编译后的表现模式,而 Matcher 则是基于该模式对输入字符串进行匹配检查的状态机。由于 Java 基于 Unicode 编码,这些模式同样适用于国际化应用。

第 1 步:配置 Pattern 编译参数

目的:将正则表达式编译为可重复使用的模式对象。

入口:Pattern.compile() 静态方法。

动作:传入正则表达式字符串 regex 及可选的标志位 flag。例如使用 Pattern.CASE_INSENSITIVE 标志可以实现不区分大小写的匹配。

第 2 步:获取并执行 Matcher 匹配

目的:在特定字符串上应用已编译的模式。

入口:调用 Pattern.matcher(CharSequence input)。

动作:传入待处理的 input 字符串获得 Matcher 实例,随后调用 matches()(整体匹配)、lookingAt()(头部匹配)或 find()(寻找子串匹配)进行操作。

第 3 步:执行高级文本操作(拆分/替换)

目的:利用正则作为分隔符或匹配规则处理整个字符串。

入口:String.split() 或 Matcher.appendReplacement()/appendTail()。

动作:可以使用 Pattern.split(input, limit) 限制分割次数;或使用 replaceAll()、replaceFirst() 配合捕获组实现复杂的字符串替换逻辑。

正则表达式语法速查

正则表达式的威力在于字符类与量词的灵活组合。以下是 Java 中常用的通配符与量词:

  • 字符类:
    • \d / \D:数字 / 非数字
    • \w / \W:单字字符 (0-9, A-Z, a-z) / 非单字字符
    • \s / \S:空白字符 / 非空白字符
    • []:自定义字符列表
    • .:匹配任意单个字符
  • 量词(控制重复次数):
    • *:0 次或多次
    • +:1 次或多次
    • ?:0 次或 1 次
    • {N,M}:最少 N 次,最多 M 次

常见应用场景与实战代码

基础字符串精确匹配

直接比较字符串是否完全符合模式,最简单的方法是使用 Pattern.matches()。

String data = "java";
// true,因为 data 完全等于模式 "java"
boolean result = Pattern.matches("java", data); 

使用量词优化匹配(+ 号用法)

模式 m(o+)n 表示以 m 开头,n 结尾,中间包含一个或多个 o。

String[] dataArr = { "moon", "mon", "moon", "mono" };
for (String str : dataArr) {
    // m(o+)n: mn中间的o可以重复一次或多次
    boolean result = Pattern.matches("m(o+)n", str);
    System.out.println(str + " 匹配结果: " + result); 
}
// 输出: moon(true), mon(false - 这里原理解析有误导,mon是m-o-n,o出现1次应该匹配,但例子中mono失败是因为末尾多了o导致整体不匹配。修正逻辑:mon匹配成功,mono匹配失败。

方括号内的字符集匹配

方括号 [] 内只能匹配单个字符。模式 b[aeiou]n 匹配 b 开头、n 结尾且中间元音字母的情况。

String[] dataArr = { "ban", "ben", "bin", "bon", "bun", "byn", "baen" };
for (String str : dataArr) {
    boolean result = Pattern.matches("b[aeiou]n", str);
    // ban, ben, bin, bon, bun 成功; byn(非元音), baen(双字符) 失败
}

多字符序列的“或”逻辑(括号与 |)

当需要匹配的中间部分超过一个字符时,需使用 () 分组配合 | 或运算符,如 (ee|ea|oo)。

String[] dataArr = { "been", "bean", "boon", "buin", "bynn" };
for (String str : dataArr) {
    boolean result = Pattern.matches("b(ee|ea|oo)n", str);
    // been, bean, boon 匹配成功
}

数字匹配(\d+)

\d 代表数字,+ 代表一次或多次,合起来匹配由纯数字组成的字符串。

String[] dataArr = { "1", "10", "101", "1010", "100+" };
for (String str : dataArr) {
    boolean result = Pattern.matches("\d+", str);
    // 前四项匹配成功,最后一项含符号“+”匹配失败
}

混合单词与数字(\w+\d+)

匹配以多个字母数字开头、以多个数字结尾的字符串。

String[] dataArr = { "a100", "b20", "c30", "df10000", "gh0t" };
for (String str : dataArr) {
    boolean result = Pattern.matches("\w+\d+", str);
    // gh0t 因数字后跟字母 t 而不匹配
}

使用正则分割字符串(Split)

String.split() 和 Pattern.split() 均支持正则。以下示例以逗号、分号或空格分割文本。

// 实例七:普通 split
String str="薪水,职位 姓名;年龄 性别";
String[] dataArr = str.split("[,\s;]");

// 实例八:Pattern split
String timeStr = "2007年12月11日";
Pattern p = Pattern.compile("[年月日]");
String[] parts = p.split(timeStr); 
// 结果为 ["2007", "12", "11"]

正则替换金额单位(replaceAll)

利用分组捕获数字和货币单位,并将单位统一替换为人民币符号。

String moneyStr = "10元 1000人民币 10000元";
// 匹配 (全数字)(单位),替换为 ¥+数字
moneyStr = moneyStr.replaceAll("(\d+)(元|人民币|RMB)", "$1¥");
// 注:Java 替换中通常使用 $1 引用第一个捕获组,若需保留数字部分应写为 "$1¥"
System.out.println(moneyStr); 

高级迭代替换(find + appendReplacement)

当需要复杂的循环处理逻辑时使用此模式。以下示例将匹配到的日期变体统一替换为标准格式。

Pattern p = Pattern.compile("m(o+)n", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher("moon mooon Mon mooooon");
StringBuffer sb = new StringBuffer();
while (m.find()) {
    m.appendReplacement(sb, "moon"); // 统一替换为 moon
}
m.appendTail(sb); // 添加剩余未匹配部分
System.out.println(sb.toString());

精确次数与范围限定({})

g(o{2,5})gle 要求 g 和 gle 之间的 o 出现 2 到 5 次。

String[] dataArr = { "google", "gooogle", "gooooogle", "goooooogle", "ggle" };
for (String str : dataArr) {
    boolean result = Pattern.matches("g(o{2,5})gle", str);
    // google(2个o-错,应为2个? google是goo,即2个o), gooogle(3个-对), gooooogole(5个-错)
    // 注: google -> g(oo)gle (2个o), gooogle -> g(o oo)gle (3个o), 依此类推
}

字符范围与范围匹配(-)

[a-c] 等同于 [abc]。

String[] dataArr = { "Tan", "Tbn", "Tcn", "Ton", "Twn" };
for (String str : dataArr) {
    boolean result = Pattern.matches("T[a-c]n", str);
    // Ton, Twn 失败,因为它们不在 a-c 范围内
}

不区分大小写匹配

使用 Pattern.CASE_INSENSITIVE 标志使匹配忽略大小写差异。

Pattern pattern = Pattern.compile("ab", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher("Ab");
if (matcher.find()) {
    System.out.println("匹配成功");
}

复杂字符串解析与 Group 提取

从混合文本中提取 XML 标签内容。 group(1) 是第一对括号的内容,group(2) 是第二对。

String regex = "<(\w+)>(\w+)</>";
Pattern pattern = Pattern.compile(regex);
String input = "<name>Bill</name><salary>50000</salary>";
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
    // group(1) 是标签名(name/salary),group(2) 是值(Bill/50000)
    System.out.println("字段: " + matcher.group(2));
}

复杂文本清洗(单词大写化)

查找形如“单词+数字”的组合,并将单词部分转为大写。

String regex = "([a-zA-Z]+[0-9]+)";
Pattern pattern = Pattern.compile(regex);
String input = "age45 salary500000 50000 title";
Matcher matcher = pattern.matcher(input);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
    // 获取第一组(字母部分)并转大写
    String replacement = matcher.group(1).toUpperCase() + matcher.group(1).length() + matcher.group().substring(matcher.group(1).length());
    // 注意:上面的替换逻辑较复杂,更简单的做法是直接构建替换串
    // 此处演示思路:保留数字,大写前面的字母
    matcher.appendReplacement(sb, replacement);
}
matcher.appendTail(sb);

以上就是 Java 正则表达式 Pattern 与 Matcher 核心用法与实战案例的详细内容,更多关于 Java 字符串处理和正则表达式技巧的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表