Java 正则表达式
                           
天天向上
发布: 2025-03-02 10:33:55

原创
845 人浏览过

Java 正则表达式(Regex,Regular Expression)是用来描述字符串模式的工具,它允许你检查一个字符串是否符合某种模式,或者通过某些规则对字符串进行匹配、替换、分割等操作。Java 中的正则表达式由 java.util.regex 包提供,包括 PatternMatcher 类。

1. 正则表达式基础

正则表达式由字符、元字符(Metacharacters)以及特殊的规则组合而成。常用的正则表达式元字符包括:

  • .:匹配任意单个字符(除换行符之外)。
  • ^:匹配输入字符串的开始。
  • $:匹配输入字符串的结束。
  • *:匹配前面的子表达式零次或多次。
  • +:匹配前面的子表达式一次或多次。
  • ?:匹配前面的子表达式零次或一次。
  • {n}:匹配前面的子表达式恰好 n 次。
  • {n,}:匹配前面的子表达式至少 n 次。
  • {n,m}:匹配前面的子表达式至少 n 次,至多 m 次。
  • []:匹配括号内的任意字符。
  • |:表示逻辑“或”。
  • ():分组,用于将多个字符或表达式作为一个单元处理。
  • \d:匹配一个数字字符,相当于 [0-9]
  • \D:匹配一个非数字字符,相当于 [^0-9]
  • \w:匹配一个字母、数字或下划线字符,相当于 [a-zA-Z0-9_]
  • \W:匹配一个非字母、非数字或非下划线字符,相当于 [^a-zA-Z0-9_]
  • \s:匹配任何空白字符(空格、制表符、换行符等)。
  • \S:匹配任何非空白字符。

2. Pattern

Pattern 类是 Java 正则表达式的核心,它是正则表达式的抽象表示。正则表达式字符串会被编译成一个 Pattern 对象,并且可以被多个 Matcher 对象重用。

2.1 创建 Pattern 对象

import java.util.regex.*;

Pattern pattern = Pattern.compile("a*b");  // 编译正则表达式

2.2 Pattern 类的常用方法

  • compile(String regex):编译正则表达式并返回 Pattern 对象。
  • matcher(CharSequence input):返回一个 Matcher 对象,用于对输入字符串进行匹配。
  • split(CharSequence input):将字符串按正则表达式分割。
  • matches():判断字符串是否完全符合正则表达式。

3. Matcher

Matcher 类提供了对字符串进行正则匹配的功能。通过 Pattern 类生成 Matcher 对象后,可以调用 Matcher 类提供的方法来执行匹配、查找、替换等操作。

3.1 创建 Matcher 对象

Pattern pattern = Pattern.compile("a*b");
Matcher matcher = pattern.matcher("aaab");

3.2 Matcher 类的常用方法

  • find():查找是否存在匹配项。如果存在,返回 true,否则返回 false
  • matches():尝试匹配整个字符串,如果字符串完全符合正则表达式,则返回 true,否则返回 false
  • group():返回当前匹配项的子字符串。
  • start():返回匹配项在原字符串中的开始位置。
  • end():返回匹配项在原字符串中的结束位置。
  • replaceAll(String replacement):用指定的字符串替换所有匹配的子串。

4. 正则表达式示例

4.1 字符串匹配

import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        // 编译正则表达式
        Pattern pattern = Pattern.compile("a*b");
        Matcher matcher = pattern.matcher("aaab");

        // 查找匹配项
        if (matcher.matches()) {
            System.out.println("字符串完全匹配");
        } else {
            System.out.println("字符串不匹配");
        }
    }
}

输出:

字符串完全匹配

4.2 查找匹配项

import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        Pattern pattern = Pattern.compile("\\d+");  // 匹配一个或多个数字
        Matcher matcher = pattern.matcher("abc123xyz456");

        // 查找匹配项
        while (matcher.find()) {
            System.out.println("找到匹配项: " + matcher.group());
        }
    }
}

输出:

找到匹配项: 123
找到匹配项: 456

4.3 使用分组

正则表达式中的分组(())可以提取字符串的一部分。

import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        Pattern pattern = Pattern.compile("(\\d+)-(\\d+)");
        Matcher matcher = pattern.matcher("123-456");

        if (matcher.find()) {
            System.out.println("第一个分组: " + matcher.group(1));  // 输出 123
            System.out.println("第二个分组: " + matcher.group(2));  // 输出 456
        }
    }
}

输出:

第一个分组: 123
第二个分组: 456

4.4 替换匹配项

import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        Pattern pattern = Pattern.compile("\\d+");  // 匹配数字
        Matcher matcher = pattern.matcher("abc123xyz456");

        // 用 "#" 替换所有的数字
        String result = matcher.replaceAll("#");
        System.out.println(result);  // 输出 abc#xyz#
    }
}

输出:

abc#xyz#

4.5 分割字符串

import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        String str = "apple,banana,orange";
        String[] fruits = str.split(",");

        for (String fruit : fruits) {
            System.out.println(fruit);
        }
    }
}

输出:

apple
banana
orange

5. 正则表达式的常用应用

5.1 验证邮箱

import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        String email = "test@example.com";
        String regex = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(email);

        if (matcher.matches()) {
            System.out.println("邮箱格式正确");
        } else {
            System.out.println("邮箱格式不正确");
        }
    }
}

输出:

邮箱格式正确

5.2 验证手机号(以中国为例)

import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        String phone = "13812345678";
        String regex = "^(1[3-9])\\d{9}$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(phone);

        if (matcher.matches()) {
            System.out.println("手机号格式正确");
        } else {
            System.out.println("手机号格式不正确");
        }
    }
}

输出:

手机号格式正确

5.3 验证密码(要求至少8个字符,包括大小写字母和数字)

import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        String password = "Password123";
        String regex = "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d).{8,}$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(password);

        if (matcher.matches()) {
            System.out.println("密码格式正确");
        } else {
            System.out.println("密码格式不正确");
        }
    }
}

输出:

密码格式正确

6. 正则表达式的性能优化

在 Java 中使用正则表达式时,通常会涉及性能方面的问题,尤其是当正则表达式较为复杂时。以下是一些性能优化的建议:

6.1 使用预编译的正则表达式

如果你在多个地方使用相同的正则表达式,推荐使用 Pattern.compile() 方法将其预编译为 Pattern 对象,这样可以避免每次使用时重复编译正则表达式,从而提高性能。

Pattern pattern = Pattern.compile("\\d+");  // 预编译正则表达式
Matcher matcher = pattern.matcher("1234");

6.2 使用非贪婪模式

默认情况下,正则表达式是贪婪的,即尽可能匹配更多的字符。有时使用非贪婪模式(即“懒惰模式”)可以提高效率,尤其是在处理大量数据时。非贪婪模式使用 *?+??? 等。

例如,".*" 是贪婪模式,会尽可能多地匹配字符,而 ".*?" 是非贪婪模式,会尽量少匹配字符。

Pattern pattern = Pattern.compile("<.*?>");  // 非贪婪模式

6.3 避免复杂的正则表达式

一些复杂的正则表达式可能会导致性能问题。尽量避免过多的分组、回溯和使用不必要的高级功能。尽量简化正则表达式,并在需要时逐步优化。

6.4 使用正则表达式时避免过多使用 find() 方法

在多次执行 find() 方法时,如果模式是 find() 调用的条件,每次调用都会使得正则表达式引擎进行多次计算。因此,当你知道需要多次查找时,可以考虑使用一次 find() 来匹配所有结果,减少多次匹配过程。

7. 正则表达式的常见应用场景

正则表达式在实际开发中有广泛的应用,以下是一些常见的应用场景:

7.1 字符串验证

正则表达式常常用于对用户输入进行验证。例如,验证邮箱、手机号、身份证号等格式是否正确。

import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        String email = "user@example.com";
        String regex = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$";

        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(email);

        if (matcher.matches()) {
            System.out.println("有效邮箱");
        } else {
            System.out.println("无效邮箱");
        }
    }
}

7.2 文本搜索与替换

正则表达式可以用来查找和替换字符串中的某些内容。例如,删除文本中的 HTML 标签或替换敏感词。

import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        String text = "This is a <b>test</b> message.";
        String regex = "<[^>]*>";  // 匹配 HTML 标签

        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text);

        // 替换 HTML 标签
        String result = matcher.replaceAll("");
        System.out.println(result);  // 输出 "This is a test message."
    }
}

7.3 从文本中提取信息

正则表达式非常适合用来从文本中提取出特定的信息。例如,从日志文件中提取 IP 地址、日期或其他关键信息。

import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        String log = "192.168.1.1 - - [12/Mar/2025:15:20:01 +0000] \"GET /index.html\"";
        String regex = "(\\d+\\.\\d+\\.\\d+\\.\\d+)";  // 提取 IP 地址

        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(log);

        if (matcher.find()) {
            System.out.println("IP 地址: " + matcher.group(1));
        }
    }
}

输出:

IP 地址: 192.168.1.1

7.4 分析与处理文件格式

在处理 CSV、日志文件、XML、JSON 等文件格式时,正则表达式是一个非常强大的工具。例如,处理 CSV 文件中的字段分隔、XML 标签的提取等。

import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        String csv = "name,age,city\nAlice,30,New York\nBob,25,Boston";
        String regex = "(\\w+),(\\d+),(\\w+)";  // CSV 文件中的每一行

        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(csv);

        while (matcher.find()) {
            System.out.println("Name: " + matcher.group(1) + ", Age: " + matcher.group(2) + ", City: " + matcher.group(3));
        }
    }
}

输出:

Name: Alice, Age: 30, City: New York
Name: Bob, Age: 25, City: Boston

8. 总结

  • 正则表达式的基本概念:通过使用元字符和特殊语法,正则表达式允许你描述和匹配复杂的字符串模式。
  • 常见方法:通过 PatternMatcher 类,你可以在 Java 中使用正则表达式进行字符串匹配、替换、分割和提取操作。
  • 应用场景:正则表达式在验证输入、文本处理、日志分析、文件解析等方面具有广泛应用。
  • 优化:合理使用预编译、非贪婪模式以及避免过于复杂的正则表达式,有助于提高性能。

如果有其他更复杂的正则表达式问题或具体的应用场景,欢迎继续提问!

发表回复 0

Your email address will not be published. Required fields are marked *