Java 正则表达式【基本语法】

基本介绍

首先我们需要了解的是正则表达式中的各种元字符的功能,主要分为以下几种:

  1. 限定符
  2. 选择匹配符
  3. 分组组合和反向引用符
  4. 特殊字符
  5. 字符匹配符
  6. 定位符

需要注意的是:在 Java正则表达式中,两个斜杠 \\ 相当于其它语言中的一个斜杠 \ 。

字符匹配符

符号 含义 示例 解释
可以匹配的字符列表 abcjs a、b、c、j、s都可以匹配到
\^ 不可以被匹配的字符列表 \^abc a、b、c不可以被匹配
- 连字符 a-z 可以匹配任意a到z的字母
. 匹配除 \n 之外的任何字符 a..b 以a开头b结尾的字符串,中包括任意两个字符
\\d 匹配单个数字字符 \\d{3}(\\d)? 匹配连续3个或4个数字的字符串
\\D 匹配非数字字符 \\D(\\d)* 以单个非数字字符开头,后面接任意个数字的字符串
\\w 匹配单个数字、英文字符、下划线 \\d{3}\\w{4} 以3个数字字符开头的长度为7的数字字母字符串
\\W 匹配单个非数字、非英文字符、非下划线 \\W+\\d{2} 以至少一个非数字字母字符开头,两个数字字符结尾的字符串
\\s 匹配任何空白字符(空格,制表符等)
\\S 匹配任何非空白字符,和\s刚好相反

Java 正则表达式默认是区分大小写的,如何实现不区分大小写?

|-------------------------------------------------|---------------------|
| (?i)abc​​​ | abc 都不区分大小写 |
| a(?i)bc | bc 不区分大小写 |
| a((?i)b)c | 只有 b不区分大小写 |
| Pattern.compile(regex,Pattern.CASE_INSENSITIVE) | 方法参数内设置忽略大小写 |

选择匹配符

符号 含义 示例 解释
| 或者的意思 ab|cd 匹配ab或者cd

用于在匹配时有选择的降低匹配标准。

限定符

用于指定其前面的字符和组合项连续出现多少次

符号 含义 示例 说明 示例
* 重复0次或n次 (abc)* 以abc开头的,子串只包含abc的字符串 abc,abcabc
+ 重复1次或多次 (abc)+ 至少以1个abc开头,子串只包含abc的字符串 abc,abcabc
? 重复0次或1次 (abc)? 以abc开头的字符串 abc
{n} 限定只能出现n次 a-d{3} 由连续的 a、b、c、d组成的字符串中任意长度为3子串

定位符

规定要匹配的字符在字符串中出现的位置,比如是在字符串开始还是在结束处。

符号 含义
^ 开头
$ 结尾
\\b 匹配目标字符串的边界,子串之间的空格
\B 匹配字符的非边界

这里主要演示一下 \\b 和 \\B :

java 复制代码
public static void main(String[] args) {
        String content = "我爱学习 学习不爱我 学习很快乐";

        String regex = "学习\\B";
        Pattern compile = Pattern.compile(regex);
        Matcher matcher = compile.matcher(content);
        while (matcher.find()){
            System.out.println(matcher.group());
        }
    }

当我们设置匹配语句为 \\b 的时候,输出结果:

java 复制代码
学习

当我们设置匹配语句为 \\B 的时候,输出结果:

java 复制代码
学习
学习

可以看到,\\b 匹配的是子串"学习"后是空格的,而 \\B 刚好相反。

分组

捕获分组

我们上一篇博客写过分组的案例,也就是 group(0),group(1)这种,也叫做非命名捕获。

这里主要介绍一种新的分组方法,叫做命名捕获,也就是说我们可以自定义组的名字。相比较之前的哪一种,它既可以使用非命名捕获(通过组号获取匹配的子串),也可以通过自定义的名字来捕获。

语法:<?<name><pattern>>

其中,需要先写一个问号?,<name>是我们对组的命名,不要太离谱就行;<pattern>是我们的正则表达式,和非命名捕获是一样的。

java 复制代码
String content = "sajnj ax1122s sjnaj4529 s584";

        String regex = "(?<group1>\\d\\d)(?<group2>\\d\\d)";
        Pattern compile = Pattern.compile(regex);
        Matcher matcher = compile.matcher(content);
        while (matcher.find()){
            System.out.println(matcher.group("group1"));
            System.out.println(matcher.group("group2"));
        }

非捕获分组

Java正则表达式中的不捕获匹配(Non-capturing Group)指的是使用括号来分组匹配,但不会将该分组的匹配结果保存到匹配结果中。这样可以在正则表达式中使用括号进行逻辑分组,但不会捕获分组的内容,从而减少内存开销并提高性能。

也就是说,虽然有括号但是不算是一个组,你使用组索引 matcher.group(n) 是获取不到结果的。

java 复制代码
String content = "industries industry";

        Pattern pattern = Pattern.compile("industr(?:y|ies)");

        Matcher matcher = pattern.matcher(content);

        while (matcher.find()){
            System.out.println(matcher.group(0));
        }

输出:

java 复制代码
industries
industry
常用分组构造形式 说明
(?:pattern) 匹配 pattern 但不捕获该匹配的子表达式,即它是一个非捕获匹配,常用来代替我们的或( | )语句。
(?=pattern) 它是一个非捕获匹配(正向预查)。例如 "Windows (?=95|98|NT|2000)" 匹配 "Windows 2000"中的 "Windows",但不匹配 "Windows 3.1"中的 "Windows'。 "(?=95|98|NT|2000)":正向预查,用于确定在匹配 "Windows" 后面的字符串是 "95"、"98"、"NT" 或者 "2000"。它使用了竖线字符 "|" 来表示 "或" 的关系,即满足其中一个条件即可。注意,这个预查不会消费输入字符串,也不会将 "95"、"98"、"NT" 或者 "2000" 匹配结果保存到匹配结果中。 因此,这个正则表达式可以匹配"Windows95"、"Windows98"、"WindowsNT" 和"Windows2000",但不会匹配 "WindowsXP" 或者"Windows10"。它可以用于查找包含特定版本的 "Windows" 字符串,用于特定的匹配需求。
(?!attern) 它也是一个非捕获匹配(负向预查)。假设有一个正则表达式 (?!abc),它表示匹配任意一个不以 "abc" 结尾的字符串。例如 "Windows (?=95|98|NT|2000)" 匹配 "Windows XP"中的 "Windows",但不匹配 "Windows 2000"中的 "Windows'。

正向预查

java 复制代码
String content = "My operating system is Windows 11,his operating system is Windows XP";

        Pattern pattern = Pattern.compile("Windows (?=11|XP)");

        Matcher matcher = pattern.matcher(content);

        while (matcher.find()){
            System.out.println(matcher.group(0));
        }

运行结果:

java 复制代码
Windows
Windows

调试正则表达式后,发现 (?=pattern)这种非捕获分组,它必须满足括号后面的条件才能被匹配,但是比如"Windows (?=11|XP)",要被匹配到的只可能是 "Windows 11" 或者 "Windows XP",但是这里的"11"和"XP"不会被保存到结果。

负向预查

java 复制代码
String content = "My operating system is Windows 11,his operating system is Windows XP";

        Pattern pattern = Pattern.compile("Windows (?!8|9|10)");

        Matcher matcher = pattern.matcher(content);

        while (matcher.find()){
            System.out.println(matcher.group(0));
        }

运行结果:

java 复制代码
Windows
Windows

调试正则表达式后,发现 (?!pattern)这种非捕获分组,它必须满足括号后面的条件才能被匹配,但是比如"Windows (?=11|XP)",要被匹配到的只可能是除了 "Windows 11" 和 "Windows XP"之外的其他"Windows xxxx"的字符串,而且这里的"xxxx"同样不会被保存到结果。

相关推荐
开开心心就好2 分钟前
图片白底怎么去掉?抠图工具抠完背景透明
java·服务器·开发语言·pdf·ocr·散列表·启发式算法
东方芷兰22 分钟前
Agent 技术摘要 05 —— BP、SaaS、B2B、C2B、B2C
java·笔记·python·语言模型·自然语言处理
Chen—LSN31 分钟前
数据结构——拿捏复杂度
java·c语言·开发语言·数据结构·经验分享·笔记·算法
一条破秋裤34 分钟前
Linux 线程同步:条件变量
java·linux·jvm
步行cgn37 分钟前
Spring AOP 切面的先后顺序详解
java·spring
ym hyd 1111 小时前
宝宝早教服务系统源码 Java+SpringBoot+Vue3 前后分离
java·开发语言·spring boot
自强的小白1 小时前
微服务之间的依赖传递和调用(实体类的模块传递以及负载均衡的调用!)注册中心
java·微服务
她说彩礼65万1 小时前
C语言 单引号与双引号
java·服务器·c语言
知守观1 小时前
百万级数据导出OOM:POI的坑与EasyExcel的流式写入实战(附内存对比)
java·后端
anew___1 小时前
《从零手写操作系统 (19):Ext2文件系统实战——从内存到磁盘的跨越》
java·服务器·前端·数据库·算法