跳转至

Java正则表达式速查表(Regex Java Cheat Sheet)

简介

正则表达式(Regular Expressions,简称Regex)是一种用于描述字符串模式的工具。在Java中,正则表达式被广泛应用于字符串的匹配、查找、替换和分割等操作。这份Java正则表达式速查表将帮助你快速掌握正则表达式在Java中的基础概念、使用方法、常见实践及最佳实践。

目录

  1. 基础概念
  2. 使用方法
    • 匹配
    • 查找
    • 替换
    • 分割
  3. 常见实践
    • 验证电子邮件地址
    • 验证电话号码
    • 提取URL
  4. 最佳实践
    • 预编译正则表达式
    • 避免复杂度过高的正则表达式
    • 使用命名捕获组
  5. 小结
  6. 参考资料

基础概念

字符类

  • [abc]:匹配方括号内指定的任意一个字符,如[abc]可以匹配abc
  • [^abc]:匹配不在方括号内指定的任意一个字符,即取反。
  • [a-zA-Z]:匹配任意一个大小写字母。
  • [0-9]:匹配任意一个数字。

预定义字符类

  • .:匹配任意一个字符(除了换行符\n)。
  • \d:匹配任意一个数字,等价于[0-9]
  • \D:匹配任意一个非数字字符,等价于[^0-9]
  • \s:匹配任意一个空白字符,包括空格、制表符、换行符等。
  • \S:匹配任意一个非空白字符。
  • \w:匹配任意一个单词字符,包括字母、数字和下划线,等价于[a-zA-Z0-9_]
  • \W:匹配任意一个非单词字符,等价于[^a-zA-Z0-9_]

数量词

  • *:匹配前面的字符零次或多次。例如,a*可以匹配空字符串、aaaaaa等。
  • +:匹配前面的字符一次或多次。例如,a+可以匹配aaaaaa等,但不能匹配空字符串。
  • ?:匹配前面的字符零次或一次。例如,a?可以匹配空字符串或a
  • {n}:匹配前面的字符恰好n次。例如,a{3}只能匹配aaa
  • {n,}:匹配前面的字符至少n次。例如,a{3,}可以匹配aaaaaaaaaaaa等。
  • {n,m}:匹配前面的字符至少n次,最多m次。例如,a{3,5}可以匹配aaaaaaaaaaaa

分组

使用圆括号()进行分组。例如,(ab)+表示ab这个组合出现一次或多次。分组可以用于捕获匹配的内容,也可以用于对一组字符应用数量词。

捕获组

在分组中,从左到右,每一个左括号(开始的分组为一个捕获组。捕获组可以在后续操作中引用。例如,(a(b)c)中有两个捕获组,第一个捕获组捕获abc,第二个捕获组捕获b

使用方法

匹配

在Java中,可以使用java.util.regex.Patternjava.util.regex.Matcher类来进行正则表达式的匹配。

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

public class RegexMatchExample {
    public static void main(String[] args) {
        String regex = "\\d+"; // 匹配一个或多个数字
        String input = "123abc456";

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

        if (matcher.find()) {
            System.out.println("匹配到的内容: " + matcher.group());
        } else {
            System.out.println("未找到匹配内容");
        }
    }
}

查找

使用Matcher类的find()方法可以查找所有匹配的子字符串。

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

public class RegexFindExample {
    public static void main(String[] args) {
        String regex = "\\d+"; // 匹配一个或多个数字
        String input = "123abc456def789";

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

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

替换

使用Matcher类的replaceAll()方法可以替换所有匹配的子字符串。

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

public class RegexReplaceExample {
    public static void main(String[] args) {
        String regex = "\\d+"; // 匹配一个或多个数字
        String input = "123abc456def789";
        String replacement = "X";

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

        String result = matcher.replaceAll(replacement);
        System.out.println("替换后的字符串: " + result);
    }
}

分割

使用Pattern类的split()方法可以根据正则表达式分割字符串。

import java.util.regex.Pattern;

public class RegexSplitExample {
    public static void main(String[] args) {
        String regex = "\\s+"; // 匹配一个或多个空白字符
        String input = "Hello   World   Java";

        Pattern pattern = Pattern.compile(regex);
        String[] parts = pattern.split(input);

        for (String part : parts) {
            System.out.println(part);
        }
    }
}

常见实践

验证电子邮件地址

import java.util.regex.Pattern;

public class EmailValidator {
    private static final String EMAIL_PATTERN =
        "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}$";

    private static final Pattern pattern = Pattern.compile(EMAIL_PATTERN);

    public static boolean validate(String email) {
        return pattern.matcher(email).matches();
    }

    public static void main(String[] args) {
        String email1 = "[email protected]";
        String email2 = "invalid-email";

        System.out.println(validate(email1)); // true
        System.out.println(validate(email2)); // false
    }
}

验证电话号码

import java.util.regex.Pattern;

public class PhoneNumberValidator {
    private static final String PHONE_NUMBER_PATTERN =
        "^\\d{3}-\\d{3}-\\d{4}$";

    private static final Pattern pattern = Pattern.compile(PHONE_NUMBER_PATTERN);

    public static boolean validate(String phoneNumber) {
        return pattern.matcher(phoneNumber).matches();
    }

    public static void main(String[] args) {
        String phone1 = "123-456-7890";
        String phone2 = "1234567890";

        System.out.println(validate(phone1)); // true
        System.out.println(validate(phone2)); // false
    }
}

提取URL

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

public class UrlExtractor {
    private static final String URL_PATTERN =
        "https?://(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}(?:/[^\\s]*)?";

    private static final Pattern pattern = Pattern.compile(URL_PATTERN);

    public static void extractUrls(String text) {
        Matcher matcher = pattern.matcher(text);
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }

    public static void main(String[] args) {
        String text = "Visit my website at https://www.example.com and check out https://example.org";
        extractUrls(text);
    }
}

最佳实践

预编译正则表达式

多次使用同一个正则表达式时,应预编译Pattern对象,而不是每次都调用Pattern.compile()

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

public class PrecompiledRegexExample {
    private static final Pattern pattern = Pattern.compile("\\d+");

    public static void main(String[] args) {
        String input1 = "123abc";
        String input2 = "def456";

        Matcher matcher1 = pattern.matcher(input1);
        Matcher matcher2 = pattern.matcher(input2);

        if (matcher1.find()) {
            System.out.println("匹配到的内容: " + matcher1.group());
        }
        if (matcher2.find()) {
            System.out.println("匹配到的内容: " + matcher2.group());
        }
    }
}

避免复杂度过高的正则表达式

复杂的正则表达式不仅难以理解和维护,而且可能导致性能问题。尽量将复杂的匹配逻辑拆分成多个简单的正则表达式。

使用命名捕获组

在Java 9及以上版本中,可以使用命名捕获组,使代码更易读。

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

public class NamedGroupExample {
    public static void main(String[] args) {
        String regex = "(?<firstName>[a-zA-Z]+) (?<lastName>[a-zA-Z]+)";
        String input = "John Doe";

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

        if (matcher.find()) {
            System.out.println("名字: " + matcher.group("firstName"));
            System.out.println("姓氏: " + matcher.group("lastName"));
        }
    }
}

小结

正则表达式在Java中是一个强大的工具,用于字符串的处理。通过掌握基础概念、使用方法、常见实践和最佳实践,你可以更高效地使用正则表达式来解决各种字符串相关的问题。希望这份速查表能帮助你在Java开发中更熟练地运用正则表达式。

参考资料