Java知识点:正则表达式

本文详细介绍了Java中的正则表达式,包括概念、用途、元字符、预定义字符类、量词、Pattern与Matcher类的使用、捕获组group、非捕获组、贪婪匹配与非贪婪匹配等核心概念,旨在帮助开发者全面理解并熟练运用正则表达式进行字符串处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1. 概念

2. 用途

3. 元字符

4. 预定义字符类

5. 量词

6. 常用类:Pattern,Matcher

7. 捕获组group()

8. 非捕获组

9. 贪婪匹配与非贪婪匹配

10. 补充


1. 概念

正则表达式是一种可以用于模式匹配和替换的规范。

一个正则表达式就是由普通字符,以及特殊字符(12个元字符)组成的文字模式。

用以描述在查找文字主体时待匹配的一个或多个字符串。

正则表达式作为一个模版,将某个字符模式与所搜索的字符串进行匹配。

2. 用途

字符串匹配(字符匹配)

字符串查找

字符串替换

字符串分割

3. 元字符

^:匹配输入字符串的开始位置。如果在方括号表达式中使用,则表示不接受该字符集合

$:匹配输入字符串的结尾位置。

():标记一个子表达式(捕获组)的开始和结束位置。

*:匹配前面的子表达式零次或多次。

+:匹配前面的子表达式一次或多次。

?:匹配前面的子表达式零次或一次,或指明一个非贪婪限定符(JMeter正则提取器中用到)。

.:匹配除换行符\n之外的任何单字符。

 \:转义,将下一个字符标记为特殊字符,或原义字符,或向后引用,或八进制转义符。

[:标记一个中括号表达式的开始。

{:标记限定符表达式的开始。

|:指明两项之间的一个选择。

                  

4. 预定义字符类

\t:制表符,等同 /u0009

\n:换行符,等同 /u000A

\d:代表一个数字,等同于 [0-9]

\D:代表非数字,等同于[^0-9]

 \s:代表换行符,Tab制表符等空白符

\S:代表非空白字符

\w:代表字母字符,等同于[a-zA-Z_0-9]

\W:代表非字母字符,等同于 [^/w]

                   

5. 量词

当要匹配的正则表达式里有一部分重复多次时,可以用量词来进行匹配固定或不定次数的重复。

X?:零次或一次

X*:零次或多次

X+:一次或多次

X{n}:恰好n次

X{n,}:至少n次

X{n,m}:至少n次,但不超过m次

                   

6. 常用类:Pattern,Matcher

示例:

Pattern p= Pattern.compile("a*b");         //a*b是被编译的正则表达式

Matcher m = p.matcher("aaaaab");         //aaaaab是待匹配的表达式

boolean b = m.matches();         //b是匹配结果,返回boolean

等价于:

boolean b = Pattern.matches("a*b", "aaaaab");

注意:

Matcher类中的matches()方式进行完全匹配。find()方法进行部分匹配。

(1)matches !!!

作用:编译给定正则表达式,并尝试将给定输入与其匹配。

语法:public static boolean matches(String regex,  CharSequence input)

抛出异常:PatternSyntaxException - 如果表达式的语法无效

使用:

方式一:Pattern.matches(regex, input);

方式二:Pattern.compile(regex).matcher(input).matches() ;

如果要多次使用一种模式,编译一次后重用此模式比每次都调用此方法效率更高。

参数:

regex - 要编译的表达式

input - 要匹配的字符序列

补充:

String类中的matches()方法是调用Pattern类中的matches()方法。 

String类中的contains()方法也可以判断一个字符串中是否包含某个子串。

(2)find!!!

作用:此方法从匹配器区域的开头开始,如果该方法的前一次调用成功了,并且从那时开始匹配器没有被重置,则从以前一次匹配操作没有匹配的第一个字符开始,继续往下匹配。

语法:public boolean find()        //尝试查找与该模式匹配的输入序列的下一个子序列。

说明:

如果匹配成功,则可以通过 start、end 和 group 方法获取更多信息。 

matcher.start() :返回匹配到的子字符串在字符串中的索引位置。

matcher.end() :返回匹配到的子字符串的最后一个字符在字符串中的索引位置。

matcher.group() :返回匹配到的子字符串。

返回:当且仅当输入序列的子序列匹配此匹配器的模式时才返回 true。

示例:

package com.my.demo;

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

public class GroupDemo {

    public static void main(String[] args) {
        Pattern p = Pattern.compile("^[A-Z][a-zA-Z0-9_]{5,15}$"); //正则表达式
        String ma="Sheryl666";  //要匹配的字符串
        Matcher m = p.matcher(ma);  
        boolean b = m.matches(); //b为匹配结果,boolean值
        System.out.println(b);
    }
}

运行结果:

true

Process finished with exit code 0

7. 捕获组group()

(1)定义:

捕获组group是以括号对"()"分割出的子Pattern,有几个括号就表示有几个组。

在JAVA中使用正则表达式返回符合正则表达式的字符串,就要用到group()。

group中记录了所有符合指定表达式的字符串。

(2)说明:

表达式((A)(B(C))中,存在四个组:

0组:表示整个表达式

1组:表示((A)(B(C)))

2组:表示 (A)

3组:表示(B(C))

4组:表示(C)

示例1:

public class GroupDemo {
    public static void main(String[] args) {
        Pattern p = Pattern.compile("(\\d+,)(\\d+)");  //首先创建Pattern对象,在其中编译要用到的表达式
        String s = "123,456-34,345";  
        Matcher m = p.matcher(s);  //接着使用matcher方法在字符串中匹配指定表达式

        //输出查找结果了,在调用m.group之前,一定要记着调用m.find,不然会产生编译错误
        //在正则表达式中,用括号括起来的算作一组
        //group(0)于group()等价,表示整个正则表达式的匹配字符串,可能有多个匹配结果,通过循环逐个打印
        //group(1)等价于第一个括号内的表达式返回的字符串,以此类推
        //当while循环执行过一轮,第二轮就输出第二组匹配的字符串
        while(m.find()) {
            System.out.println("m.group():" + m.group()); //打印一个完整的匹配结果
            System.out.println("m.group(1):" + m.group(1)); //打印第一个(\d+,)
            System.out.println("m.group(2):" + m.group(2)); //打印第二个(\d+)
            System.out.println("*********************");
        }

        System.out.println("捕获个数:groupCount()="+m.groupCount());
    }
}

运行结果:

m.group():123,456
m.group(1):123,
m.group(2):456
*********************
m.group():34,345
m.group(1):34,
m.group(2):345
*********************
捕获个数:groupCount()=2

Process finished with exit code 0

解析:

1)首先创建Pattern对象,在其中编译要用到的表达式。

2)接着使用matcher方法在字符串中匹配指定表达式。

3)然后输出查找结果了,在调用m.group之前一定要记着调用m.find(find()方法返回布尔值,即是否有找到一个符合正则表达式的字符串)。不然会产生编译错误。

4)在正则表达式中,用括号括起来的算作一组,group(0)和group()等价,表示整个正则表达式的匹配字符串(注意:这里是指匹配到的实际字符串,不是正则表达式),group(1)等价于第一个括号内的表达式返回的字符串,以此类推。

当while循环执行过一轮,第二轮就输出第二组可以整个匹配的字符串。

示例2:

public class GroupDemo {

    public static void main(String[] args) {
        String str = "aabcdfabchhhbckkkaaabcc";
        Pattern p = Pattern.compile("(((a+)b)c)");
        Matcher m = p.matcher(str);

        while(m.find()) {
            System.out.println(m.start());
            System.out.println(m.end());
            System.out.println(m.group());
            System.out.println("*********************");
        }
    }
}

运行结果:

0
4
aabc
*********************
6
9
abc
*********************
17
22
aaabc
*********************

Process finished with exit code 0

           

8. 非捕获组

定义:以?开头的组是纯的非捕获组,它不捕获文本,也不针对组合进行计数。

即,如果小括号中以?开头,那么这个分组就不会捕获文本,当然也不会有组的编号。

(?=X):仅当子表达式X在此位置的右侧匹配时才能继续匹配

(?!X):仅当子表达式X不在此位置的右侧匹配时才能继续匹配

( ?<=X):仅当子表达式X在此位置的左侧匹配时才继续匹配

(?<!X):仅当子表达式X不在此位置的左侧匹配时才能继续匹配

举例:

(?<!4)56(?=9)这里就是匹配后面的文本56前面不能是4,后面必须是9组成的。

                   

9. 贪婪匹配与非贪婪匹配

贪婪匹配:正则表达式一般趋向于最大长度匹配

非贪婪匹配:匹配到结果就好,最少的匹配字符

默认是贪婪模式,在量词后面加上一个?就是非贪婪模式。

                   

10. 补充

(1)正则的api在java.util.regex里。一般我们需要的api, 都在rt.jar里。

(2)用得最多的就是 . * +

(3)待核实的问题:matcher里的matches 方法和 find方法,用一次mathes之后,要用find,需要重新设置matcher?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值