Java 正则表达式 完整详解(语法 + 核心类 + 常用方法 + 实战案例)

目录

[一、基础正则语法(通用规则,Java 需转义)](#一、基础正则语法(通用规则,Java 需转义))

[1. 元字符(核心匹配符号)](#1. 元字符(核心匹配符号))

[2. 量词(控制匹配次数)](#2. 量词(控制匹配次数))

[3. 范围、分组、或逻辑](#3. 范围、分组、或逻辑)

[二、Java 正则核心类 & 两大使用方式](#二、Java 正则核心类 & 两大使用方式)

[方式 1:便捷字符串内置方法(简单场景)](#方式 1:便捷字符串内置方法(简单场景))

[1. boolean matches(String regex)](#1. boolean matches(String regex))

[2. String\[\] split(String regex)](#2. String[] split(String regex))

[3. String replaceAll(String regex, String replacement)](#3. String replaceAll(String regex, String replacement))

[4. String replaceFirst(String regex, String replacement)](#4. String replaceFirst(String regex, String replacement))

[方式 2:Pattern + Matcher(复杂场景:查找、分组、多次匹配)](#方式 2:Pattern + Matcher(复杂场景:查找、分组、多次匹配))

执行流程(固定三步)

[1. Pattern 常用静态 / 实例方法](#1. Pattern 常用静态 / 实例方法)

[2. Matcher 核心方法(重点)](#2. Matcher 核心方法(重点))

[(1)boolean matches() 全串匹配](#(1)boolean matches() 全串匹配)

[(2)boolean find() 查找子串(核心!)](#(2)boolean find() 查找子串(核心!))

[(3)String group() 获取匹配到的内容](#(3)String group() 获取匹配到的内容)

[(4)start() / end()](#(4)start() / end())

三、完整实战代码(分组提取、循环查找)

[案例 1:提取所有手机号(11 位数字)](#案例 1:提取所有手机号(11 位数字))

[案例 2:分组提取(提取 姓名 + 年龄)](#案例 2:分组提取(提取 姓名 + 年龄))

[案例 3:过滤特殊字符、清洗文本](#案例 3:过滤特殊字符、清洗文本)

[四、贪婪匹配 vs 非贪婪匹配(高频踩坑点)](#四、贪婪匹配 vs 非贪婪匹配(高频踩坑点))

五、常用业务正则模板(直接复制使用)

六、开发最佳实践


Java 正则基于 java.util.regex 包实现,核心三大类:Pattern(正则模板)、Matcher(匹配器)、PatternSyntaxException(正则语法异常)。

一、基础正则语法(通用规则,Java 需转义)

Java 字符串中反斜杠 \ 是转义符 ,所以正则里的 \ 必须写成 \\

1. 元字符(核心匹配符号)

符号 作用 Java 写法
. 匹配任意单个字符(除换行) .
\d 数字 0-9 \\d
\D 非数字 \\D
\s 空白符(空格、制表、换行) \\s
\S 非空白符 \\S
\w 单词字符(字母、数字、下划线) \\w
\W 非单词字符 \\W
^ 开头 ^
$ 结尾 $

2. 量词(控制匹配次数)

符号 含义
X? X 出现 0 次或 1 次(可有可无)
X* X 出现 0 次、1 次、多次
X+ X 出现 至少 1 次
X{n} X 恰好出现 n
X{n,} X 至少 n
X{n,m} X 出现 n~m

3. 范围、分组、或逻辑

  • [abc]:匹配 a/b/c 任意一个
  • [a-z]:小写字母范围;[0-9] 数字
  • [^a]非 a(取反)
  • A|B:匹配 A B
  • (...)分组,可单独提取分组内容

二、Java 正则核心类 & 两大使用方式

方式 1:便捷字符串内置方法(简单场景)

String 类原生封装了正则方法,不用手动创建 Pattern/Matcher,上手最快。

1. boolean matches(String regex)

全串匹配 :整个字符串必须完全匹配正则,才返回 true

等价于正则自带 ^$ 首尾限定。

复制代码
public class RegexDemo {
    public static void main(String[] args) {
        // 匹配纯数字(1~多位)
        String num = "123456";
        boolean res1 = num.matches("\\d+");
        System.out.println(res1); // true

        // 带字母,不匹配
        String str = "123abc";
        boolean res2 = str.matches("\\d+");
        System.out.println(res2); // false
    }
}
2. String[] split(String regex)

按正则分割字符串,返回数组。

复制代码
// 按空格/多空格分割
String text = "Java  Python   Go";
String[] arr = text.split("\\s+");
for (String s : arr) {
    System.out.println(s); // Java Python Go
}
3. String replaceAll(String regex, String replacement)

全局替换:匹配所有符合正则的内容并替换。

复制代码
// 把所有数字替换为 *
String content = "手机号:13800138000";
String newStr = content.replaceAll("\\d", "*");
System.out.println(newStr); // 手机号:***********
4. String replaceFirst(String regex, String replacement)

只替换第一个匹配项


方式 2:Pattern + Matcher(复杂场景:查找、分组、多次匹配)

复杂需求(查找子串、提取分组、循环匹配)必须用这两个类,也是工作最常用的写法。

执行流程(固定三步)
  1. Pattern.compile(正则):编译正则模板(建议全局复用,避免重复编译
  2. pattern.matcher(待匹配字符串):创建匹配器 Matcher
  3. 调用 Matcher 方法执行匹配、查找、提取

1. Pattern 常用静态 / 实例方法

复制代码
// 1. 编译正则(静态方法,最常用)
Pattern pattern = Pattern.compile("\\d+");

// 2. 简易匹配(等价于 String.matches)
boolean match = Pattern.matches("\\d+", "666");

2. Matcher 核心方法(重点)

(1)boolean matches() 全串匹配

String.matches 功能一致,要求整个字符串完全匹配

(2)boolean find() 查找子串(核心!)

从当前位置向后查找下一个匹配的子串 ,找到返回 true,可循环遍历所有匹配项。

(3)String group() 获取匹配到的内容
  • group():获取整体匹配结果
  • group(int index):获取指定分组(分组从 1 开始,0 代表整体)
  • int groupCount():获取分组总数
(4)start() / end()
  • start():匹配子串起始下标
  • end():匹配子串结束下标(后一位)

三、完整实战代码(分组提取、循环查找)

案例 1:提取所有手机号(11 位数字)

正则:1[3-9]\\d{9} 规则:1 开头,第二位 3-9,后面 9 位数字。

复制代码
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PhoneRegex {
    public static void main(String[] args) {
        String text = "联系我:13812345678,备用:15987654321";
        // 1. 编译正则
        Pattern p = Pattern.compile("1[3-9]\\d{9}");
        // 2. 创建匹配器
        Matcher m = p.matcher(text);

        // 3. 循环查找所有匹配项
        while (m.find()) {
            String phone = m.group();
            int start = m.start();
            int end = m.end();
            System.out.printf("找到手机号:%s,位置:%d ~ %d%n", phone, start, end);
        }
    }
}

输出:

复制代码
找到手机号:13812345678,位置:5 ~ 16
找到手机号:15987654321,位置:21 ~ 32

案例 2:分组提取(提取 姓名 + 年龄)

文本格式:张三(22岁),正则分组:(\\w+)\\((\\d+)岁\\)

  • 第 1 组:姓名 (\\w+)

  • 第 2 组:年龄 (\\d+)

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;

    public class GroupRegex {
    public static void main(String[] args) {
    String str = "李四(25岁)、王五(30岁)";
    Pattern p = Pattern.compile("(\w+)\((\d+)岁\)");
    Matcher m = p.matcher(str);

    复制代码
          while (m.find()) {
              String name = m.group(1); // 取第一分组
              String age = m.group(2);  // 取第二分组
              System.out.println("姓名:" + name + ",年龄:" + age);
          }
      }

    }

案例 3:过滤特殊字符、清洗文本

复制代码
public class CleanText {
    public static void main(String[] args) {
        String raw = "Hello!@#$ Java 123_";
        // 保留字母、数字、下划线,其余替换为空
        String res = raw.replaceAll("[^a-zA-Z0-9_]", "");
        System.out.println(res); // HelloJava123_
    }
}

四、贪婪匹配 vs 非贪婪匹配(高频踩坑点)

Java 正则默认贪婪 :尽可能匹配最长内容。 在量词后加 ? 变为非贪婪(最短匹配)

类型 写法 特点
贪婪 .* 匹配到最后
非贪婪 .*? 匹配到最近的结束符

示例:提取 <> 内内容

复制代码
String html = "<div>内容1</div><div>内容2</div>";

// 1. 贪婪匹配 .* (错误,一次性匹配整串)
Pattern p1 = Pattern.compile("<div>(.*)</div>");
Matcher m1 = p1.matcher(html);
if(m1.find()){
    System.out.println("贪婪:" + m1.group(1)); // 内容1</div><div>内容2
}

// 2. 非贪婪 .*? (正确,逐个匹配)
Pattern p2 = Pattern.compile("<div>(.*?)</div>");
Matcher m2 = p2.matcher(html);
while(m2.find()){
    System.out.println("非贪婪:" + m2.group(1));
}

五、常用业务正则模板(直接复制使用)

  1. 纯数字\\d+
  2. 非空字符串(不含空白)\\S+
  3. 邮箱\\w+@\\w+\\.\\w+(\\.\\w+)?
  4. 11 位手机号1[3-9]\\d{9}
  5. 去除所有空格\\s+
  6. 中文字符[\\u4e00-\\u9fa5]

六、开发最佳实践

  1. Pattern 尽量全局单例 Pattern.compile() 编译开销大,不要在循环 / 方法内频繁创建。
  2. 简单替换 / 分割 → 用 String 自带方法;查找、分组 → 必用 Pattern+Matcher
  3. 正则中 . * + ? ( ) [ ] \ 都是特殊字符,如需原样匹配 ,用 \\ 转义。
  4. 复杂正则先在线正则工具测试,再写入 Java 代码。
相关推荐
码语智行1 小时前
操作日志注解模块
java·前端·python
方也_arkling1 小时前
【Java-Day17】API篇-BigInteger和BigDecimal
java·开发语言
程序员三明治1 小时前
【AI】RAG 数据分块(Chunk)策略与实践
java·人工智能·后端·ai·大模型·llm·rag
星辰_mya1 小时前
ThreadLocal之微服务链路追踪
java·开发语言·前端
m0_617493941 小时前
PySide6/PyQt6实现中英文切换完整教程(Qt Designer + Qt Linguist + 动态切换)
开发语言·qt
松仔log1 小时前
Jetpack——DataStore
java·kotlin
咸鱼翻身小阿橙1 小时前
文件读写 + Qt Model/View + 自定义分页+搜索过滤
java·数据库·qt
在繁华处1 小时前
Java从零到熟练(十):JVM基础与性能优化
java·jvm·性能优化
眠りたいです1 小时前
现代C++:C++17中的新语言特性
开发语言·c++·c++17