正则表达式详解 + Java 实战示例
2026/6/14 5:52:56 网站建设 项目流程

目录

一、正则表达式基础概念

二、正则常用语法(核心元字符)

1. 基础匹配符

2. 预定义字符集(简写)

3. 量词(控制字符出现次数)

4. 边界匹配符

三、Java 正则核心 API 用法

四、完整 Java 代码示例

示例 1:String 内置方法(简单校验、分割、替换)

1.1 String.matches() 全串匹配(最常用:表单校验)

1.2 split() 正则分割字符串

1.3 replaceAll() 正则替换

示例 2:Pattern + Matcher 标准用法(查找、分组)

2.1 基础查找 + 判断是否匹配

2.2 分组捕获 ()(重点:提取指定片段)

示例 3:贪婪匹配 vs 非贪婪匹配

示例 4:常用实战场景合集

4.1 用户名校验(字母开头,6~16 位字母 / 数字 / 下划线)

4.2 去除所有空白符

4.3 提取所有 URL(简易版)

五、Java 正则使用最佳实践

六、常见易错点


一、正则表达式基础概念

正则表达式(Regular Expression,简称 regex):一种字符串匹配规则,用来检索、匹配、替换、分割符合规则的文本,广泛用于表单校验、日志解析、文本处理、爬虫等场景。

Java 中正则核心包:java.util.regex,核心三类:

  1. Pattern:正则表达式编译对象(不可变,线程安全)
  2. Matcher:匹配器,执行匹配、查找、替换
  3. PatternSyntaxException:正则语法异常

二、正则常用语法(核心元字符)

1. 基础匹配符

符号含义
.匹配任意单个字符(除换行符\n
\转义符,转义特殊字符(\.匹配点,\\匹配反斜杠)
[]字符集,匹配括号内任意一个字符
[^]否定字符集,匹配不在括号内的字符
``或,匹配左右任意一个表达式
()分组,将括号内视为一个整体,可捕获分组内容

2. 预定义字符集(简写)

简写等价写法含义
\d[0-9]数字
\D[^0-9]非数字
\w[a-zA-Z0-9_]字母、数字、下划线
\W[^a-zA-Z0-9_]非单词字符
\s[\t\n\r\f]空白符(空格、制表符、换行)
\S[^\s]非空白符

3. 量词(控制字符出现次数)

符号含义
?出现0 次 或 1 次(可有可无)
+出现至少 1 次
*出现0 次、1 次、多次
{n}精准出现n 次
{n,}至少 n 次
{n,m}n ~ m 次(包含两端)

贪婪 / 非贪婪:默认贪婪匹配(尽可能多匹配);加?变为非贪婪(尽可能少匹配),例:.*?

4. 边界匹配符

符号含义
^开头
$结尾
\b单词边界

完整字符串校验必须加^$,否则会部分匹配


三、Java 正则核心 API 用法

Java 中使用正则有三种常用方式

  1. String自带方法:matches()/split()/replaceAll()(简单场景)
  2. Pattern + Matcher:复杂匹配、分组、多次查找(主流)
  3. 分组捕获、循环查找、替换回调

重要提醒:Java 字符串中\必须转义为\\例:正则\d→ Java 字符串写为"\\d"


四、完整 Java 代码示例

示例 1:String 内置方法(简单校验、分割、替换)

1.1String.matches()全串匹配(最常用:表单校验)
public class RegexDemo { public static void main(String[] args) { // 1. 校验纯数字:^ 开头 $ 结尾,1个及以上数字 String numReg = "^\\d+$"; String str1 = "123456"; String str2 = "123abc"; System.out.println(str1.matches(numReg)); // true System.out.println(str2.matches(numReg)); // false // 2. 校验手机号(国内11位,以1开头) String phoneReg = "^1[3-9]\\d{9}$"; String phone1 = "13800138000"; String phone2 = "12345678901"; System.out.println(phone1.matches(phoneReg)); // true System.out.println(phone2.matches(phoneReg)); // false // 3. 校验邮箱(简易版) String emailReg = "^\\w+@\\w+(\\.\\w+)+$"; String email = "test@qq.com"; System.out.println(email.matches(emailReg)); // true } }
1.2split()正则分割字符串
// 按 数字/空格/逗号 分割 String content = "Java123Python,Go C++"; String[] arr = content.split("[\\d,\\s]+"); for (String s : arr) { System.out.print(s + " "); // Java Python Go C++ }
1.3replaceAll()正则替换
String text = "密码123,编号456,数字789"; // 把所有数字替换为 * String res = text.replaceAll("\\d+", "*"); System.out.println(res); // 密码*,编号*,数字*

示例 2:Pattern + Matcher 标准用法(查找、分组)

适用于:提取内容、分组捕获、全局查找

2.1 基础查找 + 判断是否匹配
import java.util.regex.Matcher; import java.util.regex.Pattern; public class PatternMatcherDemo { public static void main(String[] args) { String content = "订单号:ORD20260613,单号:ORD999888"; // 正则:匹配 ORD + 6位数字 String reg = "ORD\\d{6}"; // 1. 编译正则(建议复用 Pattern,提升性能) Pattern pattern = Pattern.compile(reg); Matcher matcher = pattern.matcher(content); // 2. 查找所有匹配项(循环查找) while (matcher.find()) { // group() 获取当前匹配到的完整字符串 String orderNo = matcher.group(); System.out.println("匹配到订单号:" + orderNo); } } }

输出:

匹配到订单号:ORD202606 匹配到订单号:ORD999888
2.2 分组捕获()(重点:提取指定片段)

语法:

  • group(0):匹配整个正则结果
  • group(1):第一个()分组
  • group(2):第二个()分组

需求:提取姓名-年龄格式文本中的姓名和年龄

public class GroupDemo { public static void main(String[] args) { String text = "张三-25,李四-30,王五-28"; String reg = "(\\w+)-(\\d+)"; // 分组1:姓名,分组2:年龄 Pattern pattern = Pattern.compile(reg); Matcher matcher = pattern.matcher(text); while (matcher.find()) { String name = matcher.group(1); String age = matcher.group(2); System.out.println("姓名:" + name + ",年龄:" + age); } } }

输出:

姓名:张三,年龄:25 姓名:李四,年龄:30 姓名:王五,年龄:28

示例 3:贪婪匹配 vs 非贪婪匹配

public class LazyRegex { public static void main(String[] args) { String html = "<div>内容1</div><div>内容2</div>"; // 1. 贪婪匹配 .* :一次性匹配到最后 String greedyReg = "<div>.*</div>"; Pattern p1 = Pattern.compile(greedyReg); Matcher m1 = p1.matcher(html); while (m1.find()) { System.out.println("贪婪:" + m1.group()); // 输出:<div>内容1</div><div>内容2</div> } // 2. 非贪婪匹配 .*? :最短匹配 String lazyReg = "<div>.*?</div>"; Pattern p2 = Pattern.compile(lazyReg); Matcher m2 = p2.matcher(html); while (m2.find()) { System.out.println("非贪婪:" + m2.group()); // 分行输出两个div } } }

示例 4:常用实战场景合集

4.1 用户名校验(字母开头,6~16 位字母 / 数字 / 下划线)

规则:首字符字母,后续字母数字下划线,总长度 6-16

String usernameReg = "^[a-zA-Z]\\w{5,15}$"; String u1 = "user_123"; String u2 = "123user"; System.out.println(u1.matches(usernameReg)); // true System.out.println(u2.matches(usernameReg)); // false
4.2 去除所有空白符
String str = " Java Regex Demo \t\n"; String result = str.replaceAll("\\s+", ""); System.out.println(result); // JavaRegexDemo
4.3 提取所有 URL(简易版)
String content = "官网:https://www.baidu.com 文档:http://doc.java.com"; String urlReg = "http[s]?://\\w+(\\.\\w+)+"; Pattern p = Pattern.compile(urlReg); Matcher m = p.matcher(content); while (m.find()) { System.out.println("URL:" + m.group()); }

五、Java 正则使用最佳实践

  1. 优先复用 Pattern 对象Pattern.compile()编译开销大,全局正则建议静态常量定义,不要在循环内反复编译。

    // 全局静态,只编译一次 private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");
  2. 全串校验必须加^$不加会出现 “部分匹配” 漏洞,例如正则\\d+会认为abc123是合法数字。

  3. 特殊字符必须转义. * + ? ( ) [ ] \等在正则中有特殊含义,匹配字面量时用\\转义。

  4. 分组不要滥用不需要捕获的分组,使用非捕获分组(?:表达式),不占用分组编号,性能更好。 例:(?:\\.\\w+)非捕获分组。

  5. 复杂正则拆分注释 Java 支持正则注释模式:Pattern.COMMENTS,可写备注。


六、常见易错点

  1. Java 字符串\→ 正则\\,两层转义。
  2. matches()全串匹配find()片段查找
  3. .*贪婪匹配,解析标签 / 括号务必用.*?非贪婪。
  4. \s包含换行、制表符,单纯匹配空格用 即可。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询