教程中心 / Java教程 / 正则表达式

正则表达式

12分钟 高级特性

什么是正则表达式?

正则表达式(Regular Expression)是一种强大的文本处理工具,用于匹配、查找、替换字符串。它是一种"模式描述语言",用特殊字符描述字符串的特征。

生活比喻

正则表达式就像一个"通缉令模板"。传统的方式是你写一个完整的名字去匹配,但正则表达式可以写一个"模式":姓名的第一个字是张,第二个字是两个字...这样就能匹配所有符合这个模式的人。正则表达式就是"描述模式的语言"。

正则表达式基础符号

字符类

符号含义示例
.任意单个字符a.c匹配"abc"
\d任意数字\d\d匹配"12"
\D任意非数字\D+匹配"abc"
\w单词字符[a-zA-Z0-9_]\w+匹配"hello"
\W非单词字符\W匹配"!"
\s空白字符匹配空格、制表符
[abc]字符集,a/b/c任一[aeiou]匹配元音
[^abc]排除字符集[^0-9]非数字
[a-z]字符范围[A-Za-z]所有字母

数量词

符号含义示例
*0个或多个ab*c匹配"ac"/"abc"/"abbc"
+1个或多个ab+c匹配"abc"/"abbc"
?0个或1个colou?r匹配"color"/"colour"
{n}恰好n个\d{11}匹配11位数字
{n,}至少n个\d{6,}至少6位
{n,m}n到m个\d{6,8}6到8位

位置词

符号含义示例
^字符串开头^hello匹配"hello world"
$字符串结尾world$匹配"hello world"
\b单词边界\bword\b完整单词"word"

分组和引用

符号含义示例
(abc)捕获组(\d{4})-(\d{2})两组
(?:abc)非捕获组不创建分组引用
\1引用第一个组(\w)\1重复字符

Java中如何使用正则

1. 验证:matches()

public class RegexMatchesDemo {
    public static void main(String[] args) {
        String phone = "13812345678";

        // 手机号:1开头,第二位3-9,11位数字
        boolean valid = phone.matches("^1[3-9]\\d{9}$");
        System.out.println("手机号有效: " + valid);

        // 邮箱
        String email = "user@example.com";
        boolean emailValid = email.matches("^[\\w.-]+@[\\w.-]+\\.\\w+$");
        System.out.println("邮箱有效: " + emailValid);

        // 身份证号(18位)
        String id = "110101199001011234";
        boolean idValid = id.matches("^\\d{17}[\\dXx]$");
        System.out.println("身份证有效: " + idValid);
    }
}

2. 查找:Pattern和Matcher

import java.util.regex.*;

public class RegexFindDemo {
    public static void main(String[] args) {
        String text = "订单号: A123, B456, C789";

        // 查找所有订单号
        Pattern pattern = Pattern.compile("[A-Z]\\d{3}");
        Matcher matcher = pattern.matcher(text);

        System.out.println("找到的订单号:");
        while (matcher.find()) {
            System.out.println("  位置" + matcher.start() + ": " + matcher.group());
        }
    }
}

3. 替换:replaceAll()

public class RegexReplaceDemo {
    public static void main(String[] args) {
        String text = "电话号码: 13812345678, 13998765432";

        // 手机号脱敏:138****5678
        String masked = text.replaceAll(
            "(\\d{3})\\d{4}(\\d{4})",
            "$1****$2"
        );
        System.out.println("脱敏后: " + masked);

        // 替换所有数字
        String noDigits = text.replaceAll("\\d+", "#");
        System.out.println("数字替换: " + noDigits);

        // 替换空白
        String normalized = "你    好    世    界";
        String noSpaces = normalized.replaceAll("\\s+", "");
        System.out.println("去空白: " + noSpaces);
    }
}

4. 分割:split()

public class RegexSplitDemo {
    public static void main(String[] args) {
        String csv = "苹果,香蕉,樱桃,日期";

        // 按逗号分割
        String[] fruits = csv.split(",");
        System.out.println("水果: " + java.util.Arrays.toString(fruits));

        // 按多种分隔符分割
        String mixed = "苹果,香蕉;樱桃:日期";
        String[] mixedFruits = mixed.split("[,;:]");
        System.out.println("混合分割: " + java.util.Arrays.toString(mixedFruits));

        // 按连续空白分割
        String spaced = "苹果  香蕉     樱桃";
        String[] spacedFruits = spaced.split("\\s+");
        System.out.println("空白分割: " + java.util.Arrays.toString(spacedFruits));
    }
}

常用正则表达式模板

用途正则表达式
手机号(中国)^1[3-9]\d{9}$
电子邮箱^[\w.-]+@[\w.-]+\.\w+$
URL^https?://[\w.-]+(/[\w.-]*)*/?$
IP地址^(\d{1,3}\.){3}\d{1,3}$
日期(YYYY-MM-DD)^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$
时间(HH:mm:ss)^(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d$
中文姓名^[\u4e00-\u9fa5]{2,4}$
QQ号^[1-9]\d{4,10}$
邮政编码^\d{6}$

捕获组示例

import java.util.regex.*;

public class RegexGroupDemo {
    public static void main(String[] args) {
        String text = "2026-06-15 10:30:45";

        // 提取日期和时间
        Pattern p = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2}) (\\d{2}):(\\d{2}):(\\d{2})");
        Matcher m = p.matcher(text);

        if (m.matches()) {
            System.out.println("完整匹配: " + m.group(0));  // 整个字符串
            System.out.println("年: " + m.group(1));        // 2026
            System.out.println("月: " + m.group(2));        // 06
            System.out.println("日: " + m.group(3));        // 15
            System.out.println("时: " + m.group(4));        // 10
            System.out.println("分: " + m.group(5));        // 30
            System.out.println("秒: " + m.group(6));        // 45
        }

        // 交换姓名
        String names = "Zhang San, Li Si, Wang Wu";
        String swapped = names.replaceAll("(\\w+)\\s+(\\w+)", "$2 $1");
        System.out.println("姓名交换: " + swapped);
    }
}

常见错误

错误1:忘记转义

在正则表达式中,.*等是特殊字符。如果你要匹配字面意义上的点号,需要写成\\.

// 错误:匹配任何字符
"example.com".matches(".+\\.com"); // true

// 正确:匹配字面意义的点号
"exampleXcom".matches(".+\\.com"); // false

错误2:贪婪匹配导致意外结果

.*是贪婪的,会尽可能多地匹配。使用.*?进行非贪婪匹配。

小结

  • 正则表达式是强大的文本匹配和处理工具
  • .匹配任意字符,\d匹配数字,\w匹配单词字符
  • *+?表示数量,{n,m}表示范围
  • ^$表示位置,\b表示单词边界
  • Pattern/Matcher是Java中处理正则的主要类
  • 捕获组()可以提取和复用匹配的子串
☕ Java 在线代码编辑器
📝 运行结果