您的位置:

Java正则表达式基础教程

Java正则表达式是一种强大的模式匹配工具,它用于在字符串中搜索和匹配特定模式的子串。在Java中,使用正则表达式需要使用java.util.regex包中的类。Java正则表达式的基础用法非常简单,但是灵活性和功能却非常强大,当你熟练掌握它的使用方法后,可以解决多种文本处理问题。

一、基础语法

Java正则表达式的基础语法包括以下几个内容:

1、字符集

在正则表达式中,字符集用方括号[]表示,表示一个匹配任意一个方括号中所包含的字符,在方括号中使用连字符(-)可以表示一个字符范围。例如:

String regex = "[abc]"; // 匹配a、b、c中的任何一个字符
String regex2 = "[a-d]"; // 匹配a、b、c、d中的任何一个字符
String regex3 = "[^abc]"; // 匹配除了a、b、c之外的任何一个字符

2、通配符

在正则表达式中,通配符用英文句点(.)表示,表示可以匹配任意一个字符(除了换行符)。例如:

String regex = "a.c"; // 匹配任何以a开头,以c结尾,中间是任意一个字符的字符串

3、重复次数

在正则表达式中,使用花括号{}来指定一个模式的重复次数,其中可以使用一个或两个数字,表示精确的重复次数或范围。例如:

String regex = "a{3}"; // 匹配连续的三个a
String regex2 = "a{1,3}"; // 匹配连续的1到3个a
String regex3 = "a{0,}"; // 匹配任意数量的a
String regex4 = "a+"; // 匹配一个或多个a
String regex5 = "a*"; // 匹配任意数量的a(甚至可以是0个)
String regex6 = "a?"; // 匹配0个或1个a

4、边界匹配

在正则表达式中,使用两个特殊的元字符表示一个字符串的边界,^表示字符串的开头,$表示字符串的结尾。例如:

String regex = "^abc"; // 匹配以abc开头的字符串
String regex2 = "xyz$"; // 匹配以xyz结尾的字符串
String regex3 = "^abc$"; // 匹配等于abc的字符串

5、字符转义

在正则表达式中,有些字符具有特殊含义,例如句点(.)表示任意字符,方括号([])表示字符集等,在正则表达式中使用反斜杠(\)来转义这些字符的特殊含义。例如:

String regex = "a\\.b"; // 匹配a.b的字符串
String regex2 = "\\[abc\\]"; // 匹配包含[abc]的字符串

二、高级用法

1、捕获组

在正则表达式中使用圆括号()来表示一个分组,在分组中匹配的内容可以使用捕获组来进行后续的操作。例如:

String regex = "(\\w+)\\s(\\w+)"; // 匹配一个类似“John Smith”这样的字符串,其中名字和姓氏使用空格分隔
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher("John Smith");
if (matcher.matches()) {
    String firstName = matcher.group(1);
    String lastName = matcher.group(2);
}

2、预定义字符集

在正则表达式中,有一些预定义的字符集可以用来匹配特定类型的字符,例如数字、空白字符、单词字符等等。例如:

String regex = "\\d+"; // 匹配任何一个数字
String regex2 = "\\s+"; // 匹配任何一个空白字符
String regex3 = "\\w+"; // 匹配任何一个单词字符(字母、数字、下划线)
String regex4 = "\\W+"; // 匹配除了单词字符以外的任何字符

3、零宽断言

在正则表达式中,零宽断言(Lookaround)用来查找在当前字符位置之前或之后的另一个字符串。零宽断言不匹配任何字符,它只确定当前字符位置。例如:

String regex = "John(?=\\sSmith)"; // 匹配包含John且后面紧跟着一个空格和Smith的字符串,但不包括Smith。
String regex2 = "(?<=John\\s)Smith"; // 匹配包含Smith且前面是一个以John和一个空格开头的字符串,但不包括John。

4、贪婪与懒惰

在正则表达式中,重复次数默认是贪婪的,例如如果重复次数设置为“*”时,它会尽可能地匹配更多的字符。如果想要改为懒惰的匹配,可以在重复次数后面添加个问号。例如:

String regex = "ab.*cd"; // 匹配以ab开头,以cd结尾,中间任意字符的字符串
String regex2 = "ab.*?cd"; // 匹配以ab开头,以cd结尾,中间匹配最少的字符的字符串

三、实例演示

下面的例子演示了如何使用正则表达式进行字符串匹配和替换。该例子展示了如何通过正则表达式匹配包含特定单词的Java源代码文件,并将匹配到的行替换为另一个字符串。

import java.util.regex.*;
import java.nio.file.*;

public class RegexDemo {
    public static void main(String[] args) throws Exception {
        String pattern = "\\bpublic\\b"; // 指定需要匹配的单词
        Path path = Paths.get("Hello.java"); // 指定需要搜索的Java源代码文件
        String content = new String(Files.readAllBytes(path)); // 读取文件内容
        
        Pattern regex = Pattern.compile(pattern);
        Matcher matcher = regex.matcher(content);
        
        StringBuffer result = new StringBuffer();
        while (matcher.find()) {
            String replacement = matcher.group().toUpperCase(); // 将匹配到的单词转换为大写
            matcher.appendReplacement(result, replacement);
        }
        matcher.appendTail(result); // 在最后一次匹配之后添加尾部
        
        String output = result.toString();
        System.out.println(output); // 输出替换后的文本
    }
}

在上个示例中,我们将读取一个Java源代码文件,并在其中搜索包含特定单词的行。在这里,我们使用正则表达式模式来指定需要搜索的单词,然后使用Java的NIO API将文件的内容读取成一个字符串。接下来,我们创建一个Pattern实例来编译正则表达式模式,然后使用该模式在字符串内容中查找。在每次找到匹配时,我们将匹配到的单词转换为大写,并将其附加到结果缓冲区中。最后,我们使用appendTail()方法将最后一段未匹配文本添加到结果缓冲区中,并输出替换后的文本。