正则表达式(JAVA)【提升字符串处理能力的利器】

Python和Java中的字符串处理,特别是使用正则表达式的区别 作者:禅与计算机程序设计艺术 1.背景介绍 在计算机领域里,字符串(String)是一个非常重要的数据类型,它用来存储、管理和表示文本信息。在过去几十年中,由于文本数据的快速增长和广泛应用,各种语言都开始支持字符串操作。目前比较流行的两种编程语言是Python和Java。但两者之间还有一些细微差别, 阅读详情

偷偷发博客应该没有人会看见吧 😕,如果有写错的地方欢迎指正,第一次发博客,难免有些生疏,请大家谅解。

正则表达式(JAVA语言描述)

​ 正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。

一、概念

​ 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。

二、介绍

​ 正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,该模式描述在搜索文本时要匹配的一个或多个字符串。

​ 上面的概念和介绍来自于百度,正则表达式_百度百科 (baidu.com),从描述中可见,正则表达式可以很方便地对字符串进行检索和替换,可以方便我们对于文本字串的操作。

​ 接下来我们将使用JAVA语言来进行正则表达式的学习。

JAVA正则使用流程:

​ 1、定义文本字串(String)content:

String content = "数论早期称为算术。到20世纪初,才开始使用数论的名称,";

​ 2、创建正则字符串(正则表达式):

String regStr = "\\d\\d";

​ 3、创建模式对象:

Pattern pattern = Pattern.compile(regStr);

注意::

在这里插入图片描述

这里使用的是java.util.regex中的pattern,而不是下面的包。

​ 4、创建匹配器(创建匹配器matcher,按照正则表达式的规则去匹配content字符串)

Matcher matcher = pattern.matcher(content);

​ 5、输出匹配内容:

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

​ 输出:

​	[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1f5lpbms-1651672474687)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220503205437067.png)]

三、特点

​ 正则表达式的特点是:

\1. 灵活性、逻辑性和功能性非常强;

\2. 可以迅速地用极简单的方式达到字符串的复杂控制。

\3. 对于刚接触的人来说,比较晦涩难懂。

由于正则表达式主要应用对象是文本,因此它在各种文本编辑器场合都有应用,小到著名编辑器EditPlus,大到Microsoft Word、[Visual Studio](https://baike.baidu.com/item/Visual Studio/539453)等大型编辑器,都可以使用正则表达式来处理文本内容。

四、正则表达式语法

元字符:

1、限定符

2、选择匹配符

3、分组组合和反向引用符

4、特殊字符

5、字符匹配符

6、定位符

元字符(Metacharacter)-转义号\

\\符号 说明:当在正则表达式中去检索含转义字符的字串时,需要用到转义符号,否则匹配不到结果,甚至会报错

在java正则表达式中,两个\\代表其他语言中的一个\

PS:不适用转义字符会报错:
在这里插入图片描述

使用转义字符后的正确输出:
在这里插入图片描述

为什么不用 ( 而是\\( ,因为在java语言的正则表达式中,两个斜杠\\代表其他语言中的一个斜杠\

使用转义字符的场景(常用):. * + ( ) $ / \ ? [ ] ^ { }

元字符-字符匹配符

符号示例解释
[ ]可接收的字符列表[efgh]e、f、g、h中的任意一个字符
[^]不接收的字符列表[^abc]除a、b、c以外的任意一个字符包括字母和特殊符号
-连字符(左边到右边的范围)A-Z任意单个大写字母
符号含义示例说明匹配输入
.匹配除\n以外的任何字符a…b以a开头,b结尾,中间包括2个任意字符的长度为4的字符串aaab、a#*b、a33b
\\d匹配单个数字字符相当于[0-9]\\d{3}(\\d)? 1包含三个或四个数字的字符串123、9876
\\D匹配单个非数字字符,相当于2\\D(\\d)* 3以单个非数字字符开头,后接任意个数字字符串a、A342
\\w匹配单个数字、大小写字母字符,相当于[0-9a-zA-Z_]、另外还有下划线字符。\\d{3}\\w{4}4以三个数字字符开头的长度为7的数字字母字符串234abcd、12345pe
\\W匹配单个非数字、大小写字母、下划线字符,相当于[^ 0-9a-zA-Z]\\W+\\d{2}5以至少1个非数字字母字符开头,两个数字字符结尾的字符串#29、#?@10
\\s匹配任何空白字符(空格、制表符等)
\\S与\\s相反,匹配任何非空白字符
\\.匹配.字符
例子1(小写字母):

演示字符匹配符的使用 :

一、字符串中找到所有小写字母:

String content = "ac123456sda61dx";
String RegStr = "[a-z]";

Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JPQIfYdF-1651672474688)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220503205915868.png)]

例子2(除了小写字母之外):

[^a-z]表示除了小写字母之外其他都能匹配

String content = "ac123456abcABC61dx";
String RegStr = "[^a-z]";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
      System.out.println("找到:"+matcher.group(0));
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jxmTGVeL-1651672474689)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220503211302346.png)]

正则表达式默认大小写问题:

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

第一种[使用(?i)]:
正则说明
(?i)abc表示abc都不区分大小写
a(?i)bc表示bc不区分大小写
ab(?i)c表示只有b不区分大小写

不使用(?i)之前:

String content = "ac123456abcABC61dx";
String RegStr = "abc";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uoeTGHV5-1651672474689)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220503210456141.png)]

使用(?i)之后:

String content = "ac123456abcABC61dx";
String RegStr = "(?i)abc";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-agsTpDcy-1651672474690)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220503210549561.png)]

第二种不区分大小写方式(pattern.compile()方法中增加限定参数):

规定pattern.compile()方法中的第二个参数为Pattern.CASE_INSENSITIVE,表示匹配时不区分大小写

Pattern pattern = Pattern.compile(RegStr,Pattern.CASE_INSENSITIVE);
例子3(限定参数):

由例子2中增加限定参数Pattern.CASE_INSENSITIVE,使得匹配的时候不区分大小写。

String content = "ac123456abcABC61dx";
        String RegStr = "[^a-z]";
//        Pattern pattern = Pattern.compile(RegStr,Pattern.CASE_INSENSITIVE);
        Pattern pattern = Pattern.compile(RegStr,Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(content);

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6g9IxF23-1651672474690)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220503211735624.png)]

例子4(匹配非数字):

匹配非数字:

String content = "ac123456abcABC61dx";
String RegStr = "\\D";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fGu1HmFc-1651672474691)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220503212015701.png)]

例子5(匹配大小写英文字母、数字、下划线字符):

匹配大小写英文字母、数字、下划线字符:

String content = "abc_@ABC61$";
String RegStr = "\\w";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PlzwKSBQ-1651672474691)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220503212301042.png)]

例子6(过滤空白和\t):

过滤掉段落中的空白字符和制表符:

String content = "abc_@ABC 61   $";
String RegStr = "\\S";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sMYYppFT-1651672474692)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220503213056159.png)]

注意:在对齐的情况下一个制表符等于四个空白字符:

这里每当有一个空白字符就会打印一次 找到:

String content = "abc_@A    BC61$";
String RegStr = "\\s";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6tmxQoN3-1651672474692)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220503213246897.png)]

注意:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QisUYca7-1651672474693)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220503213508715.png)]

​ A和B中间的空部分是在A已经末尾对齐的情况下敲的Tab制表符键,如果不是对齐的话敲制表符就会强制到末尾对齐位置而不是空4个空白字符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l0x7f03G-1651672474694)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220503213905649.png)]

这里第二行1的后面敲的是制表符但实际只空出3个空白字符,第三行12的后面敲的是制表符但实际只空出2个空白字符,第四行开头就敲一个制表符空出4个空白字符,文本会每隔4个空白字符一次对齐,制表符的空白字符的数量其实要根据当前文本的位置来决定,而不是固定的4个字符。

元字符-选择匹配符:

选择匹配符相当于或运算符:

符号说明示例解释
|匹配"|"之前或之后的表达式ab|cdab或者cd

元字符-限定符:

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

符号含义示例说明匹配输入
*指定字符出现0次或者n次(0-n)(abc)*仅包含任意个abc的字符串,等效于\w*abc、abcabcabc
+指定字符重复1次或者n次(至少一次)(0-n)m+(abc)*以至少一个m开头,后接任意个abc的字符串m、mabc、mabcabc
?指定字符重复0次或者1次(最多一次)m+abc?以至少一个m开头,后接ab或者abc的字符串mab、mabc、mmab、mmmabc
{n}只能输入n个字符[abcd]{3}由abcd中字母组成的任意长度为3的字符串abc、acb、cba
{n,}指定至少n个匹配[abcd]{3,}由abcd中字母组成的任意长度不少于3的字符串aab,bbc,aabbcc
{n,m}指定至少n个但不多于m个匹配[abcd]{3,5}由abcd中字母组成的任意长度不少于3、不大于5的字符串abc、bbcc、aacbc
例子1(1{4}):

1{4}

String content = "11111";
String RegStr = "1{4}";

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-slGXRA8R-1651672474695)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220503220642290.png)]

只会匹配前4个1,后面一个1不会匹配

例子2(匹配两位任意数字):
String content = "11111aa";
String RegStr = "\\d{2}";

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VxBQcjPX-1651672474696)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220503220829480.png)]

例子3(贪婪匹配):

java默认匹配方式是贪婪匹配,尽可能匹配多的。

String content = "aaaaa";
String RegStr = "a{3,5}";

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Y9gTd8t-1651672474696)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220503221129042.png)]

String content = "aaaaaa";
String RegStr = "a{3,4}";

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AIOcN0oi-1651672474696)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220503221234779.png)]

例子4(?):

?也遵守贪婪匹配

String content = "a111aaa";
String RegStr = "a1?";

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hlxY1w9r-1651672474697)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220503221727702.png)]

例子5(非贪婪匹配):
字符说明
?当此字符紧随任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式是"非贪心的"。"非贪心的"模式匹配搜索到的、尽可能短的字符串,而默认的"贪心的"模式匹配搜索到的、尽可能长的字符串。例如,在字符串"oooo"中,"o+?“只匹配单个"o”,而"o+“匹配所有"o”。
String content = "aaa1111";
String RegStr = "\\d+";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
    System.out.println("find: "+matcher.group(0));
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z6OWfJmW-1651672474698)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220504190348929.png)]

String content = "aaa1111";
String RegStr = "\\d+?";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
    System.out.println("find: "+matcher.group(0));
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wnVORYBA-1651672474698)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220504190410753.png)]

元字符-定位符:

符号含义示例说明匹配输入
^指定起始字符^[0-9]+[a-z]*以至少一个数字开头,后接任意个小写字母的字符串123、6aa、555efd
$指定结束字符^[0-9]\\-[a-z]+$以一个数字开头后接连字符-,并以至少一个小写字母结尾的字符串1-a
\\b匹配目标字符串 的边界han\\b这里说的字符串的边界指的是子串间有空格,或者是目标字符串的结束位置adssadkbahan nxhan
\\B匹配目标字符串的非边界abc\\B和\\b的含义相反12311abc abc123 1abc2
例子1(^起始字符):
String content = "12311aaa12345abc";
String RegStr = "^[0-9]+[a-z]*";

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4bqMDqMI-1651672474698)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220504092053508.png)]

例子2(^结束字符):

(限定范围)+$:代表以限定范围内的字符结尾的字符串

String content = "12311abc";
String RegStr = "^[0-9]+[a-z]+$";

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tr07gAyj-1651672474699)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220504092155280.png)]

例子3(\\b匹配边界字符串)

这里的边界既可以是整个字符串的最后,又可以是字符串空格间隔的子串的最后

String content = "12311abc abc123 abc 1abc2 ";
String RegStr = "abc\\b";

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OqbxaCtJ-1651672474700)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220504092600835.png)]

String content = "12311abc abc123 1abc2 ";
String RegStr = "abc\\b";

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fNAB8YO4-1651672474700)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220504092701958.png)]

例子4(\\B)

\\B与前面相反

String content = "12311abc abc123 1abc2 ";
String RegStr = "abc\\B";

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2enB1XUu-1651672474701)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220504092916914.png)]

分组:

常用分组:
常用分组构造形式说明
(pattern)非命名捕获。捕获匹配的子字符串。编号为零的第一个捕获是由整个正则表达式模式匹配的文本,其他捕获结果则根据左括号的顺序从1开始自动编号
(?pattern)命名捕获。将匹配的子字符串捕获到一个组名称或编号名称中。用于name的字符串不能包含任何标点符号,并且不能以数字开头,可以使用单引号代替尖括号,例如(?‘name’)
例子1(()分组):

使用()进行分组:

String content = "nbPlus1234 abs1314aaa 7777";
String RegStr = "(\\d\\d)(\\d)(\\d)";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
    System.out.println("find: "+matcher.group(0));
    System.out.println("find: "+matcher.group(1));
    System.out.println("find: "+matcher.group(2));
    System.out.println("find: "+matcher.group(3));
    
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wf1eUO5n-1651672474701)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220504182632830.png)]

例子2(命名分组):
String content = "nbPlus1234 abs1314aaa 7777";
String RegStr = "(?<s1>\\d\\d)(?<s2>\\d)(?<s3>\\d)";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
    System.out.println("find: "+matcher.group(0));
    System.out.println("find: "+matcher.group(1));
    System.out.println("find: "+matcher.group(2));
    System.out.println("find: "+matcher.group(3));

    System.out.println("find<s1>: "+matcher.group("s1"));
    System.out.println("find<s2>: "+matcher.group("s2"));
    System.out.println("find<s3>: "+matcher.group("s3"));

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0WVCEzIt-1651672474702)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220504182944024.png)]

特别分组:
常用分组构造形式说明
(?:pattern)匹配pattern但不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配。这对于用“or”字符(|)组合模式部件的情况很有用。例如(interest(?:ed|ing)是比interested|interesting更经济的表达式
(?=pattern)它是一个非捕获匹配。例如’windows (?=95|2008|10)'匹配"windows 2008"中的windows但不匹配windows 3.1中的Windows
(?!pattern)该表达式与(?=pattern)正好相反,它是一个非捕获匹配,例如’windows (?!95|2008|10)'匹配windows 3.1中的Windows但不匹配"windows 2008"中的windows
例子1:
String content = "abc1sz abc2x abc3ada";
String RegStr = "abc1|abc2|abc3";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
    System.out.println("find: "+matcher.group(0));
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0ar66eRq-1651672474702)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220504184117559.png)]

String content = "abc1sz abc2x abc3ada";
String RegStr = "abc(?:1|2|3)";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
    System.out.println("find: "+matcher.group(0));
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5jSx5A4A-1651672474703)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220504184212881.png)]

上面的abc(?:1|2|3)等同于abc1|abc2|abc3,但是虽然表达式中有括号,但不进行分组

非捕获匹配:不会将字符串存入matcher.group(1)当中,也就是说非捕获分组中的分组不会存入到group数组当中去,如果去访问group(1)会产生错误。

String content = "abc1sz abc2x abc3ada";
String RegStr = "abc(?:1|2|3)";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
    System.out.println("find: "+matcher.group(0));
    System.out.println("find: "+matcher.group(1));
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0XcmOXAx-1651672474703)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220504185640707.png)]

五、应用实例:

根据上面的内容综合一个案例:

使用正则表达式验证网站的URL格式是否正确

//验证URL
String content="https://www.bilibili.com/anime/?spm_id_from=333.1007.0.0";
//[.]表示匹配.本身
String RegStr = "^(htt(?:p|ps)://)?([\\w-]+\\.)+[\\w-]+(\\/[\\w-?=&/%.#]*)?$";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);
if(matcher.find()){
    System.out.println("匹配成功!");
}
else{
    System.out.println("匹配失败!");
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UzjbyXEq-1651672474704)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220504193858858.png)]

^(htt(?:p|ps)://)?部分,匹配https://或者http://在开头或者省略掉的字符串。

([\\w-]+\\.)+部分,匹配www.和bilibili.

[\\w-]+部分,匹配com

(\\/[\\w-?=&/%.#]*)?$部分,匹配结尾/anime/?spm_id_from=333.1007.0.0

注意([ ]的问题):

其中写在[ ]内的特殊字符,不用进行转义(\\),匹配的就是本身,比如下面的例子;

不使用[]:

String content = "aaa1.1";
String RegStr = ".";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
    System.out.println("find: "+matcher.group(0));
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PcoBeB8u-1651672474704)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220504194342049.png)]

使用[]:

String content = "aaa1.1";
String RegStr = "[.]";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
    System.out.println("find: "+matcher.group(0));
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tHTSGFqs-1651672474705)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220504194406152.png)]

六、正则表达式常用类:

java.util.regex包主要包括一下三个类Pattern类、Matcher类和PatternSyntaxException

Pattern类:

pattern对象是一个正则表达式对象。Pattern类没有公共构造方法,要创建一个Pattern对象,调用其公共静态方法,它返回一个Pattern对象。该方法接受一个正则表达式作为它的第一个参数,比如:

Pattern pattern = Pattern.compile(pattern);
matches方法:

Pattern类的matches方法,用于整体匹配,在验证输入的字符串是否满足条件使用:

下面是matches的源码:

public static boolean matches(String regex, CharSequence input) {
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(input);
    return m.matches();
}

由源码可以看出matches封装了创建模式对象和创建匹配器两步,当我们只是验证字符串是否匹配,而不进行索取的情况下,可以使用matches简化我们的写法

例子1:

对于上面第五部分的应用实例(验证URL的那个),我们实际上可以使用matches来简化我们的代码:

//验证URL
String content="https://www.bilibili.com/anime/?spm_id_from=333.1007.0.0";
//[.]表示匹配.本身
String RegStr = "^(htt(?:p|ps)://)?([\\w-]+\\.)+[\\w-]+(\\/[\\w-?=&/%.#]*)?$";

System.out.println("匹配结果:"+Pattern.matches(RegStr,content));

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oO2HSyND-1651672474705)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220504201218906.png)]

同时matches也相当于给RegStr的前面加上^后面加上$(整体匹配),常用于验证登录信息验证,邮箱验证等场景。

Matcher类:

Matcher对象是对输入字符串进行解释和匹配的引擎。与Pattern类一样,Matcher也没有公共构造方法。你需要调用Pattern对象的matcher方法来获得一个Matcher对象

方法:

方法及说明
public int start()返回以前匹配的初始索引。
public int start(int group)返回在以前的匹配操作期间,由给定组所捕获的子序列的初始索引
public int end()返回最后匹配字符之后的偏移量
public int end(int group)返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量
public boolean lookingAt()尝试将从区域开头的输入序列与该模式匹配。
public boolean find()尝试查找与该模式匹配的输入序列的下一个子序列。
public boolean find(int start) 重置此匹配器,然后尝试查找匹配该模式、从指定索引开始的输入序列的下一个子序列
public boolean matches()尝试将整个区域与模式匹配
public Matcher appendReplacement(StringBuffer sb,String replacement)实现非终端和添加替换步骤。
public StringBuffer appendTail(StringBuffer sb)实现终端添加和替换步骤
public String replaceAll(String replacement)替换模式与给定替换字符串相匹配的输入序列的每个子序列
public String replaceFirst(String replacement)替换模式与给定替换字符串相匹配的输入序列的第一个子序列
public static String quoteReplacement(String s)返回指定字符串的字面替换字符串。这个方法返回一个字符串,就像传递给Matcher类的appendReplacement方法一个字面字符串一样工作
public Matcher appendReplacement(StringBuffer sb, String replacement)实现非终端添加和替换步骤。
public StringBuffer appendTail(StringBuffer sb)实现终端添加和替换步骤。

常用:start(),end(),matches(),replaceAll()

例子1(start和end):
String content="hello jack tom cate hello ";
String RegStr = "hello";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
    System.out.println("===============");
    System.out.println(matcher.start());
    System.out.println(matcher.end());
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WkEl248c-1651672474706)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220504202308411.png)]

返回字符串匹配的开始和结束的索引值(下标)。

例子2(replaceAll()):

把hello替换成123

String content="hello jack tom cate hello ";
String RegStr = "hello";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);
String newStr = matcher.replaceAll("123");
System.out.println(newStr);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DdUOe5UD-1651672474706)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220504203847433.png)]

replaceAll()返回的才是替换之后的字符串,原来的字符串不会改变(被替换)。

异常:

PatternSyntaxException:

PatternSyntaxException是一个非强制异常类,它表示一个正则表达式中的语法错误。

七、分组、捕获和反向引用

1、分组:

​ 我们可以用圆括号组成一个比较复杂的匹配模式,那么一个圆括号的部分我们可以看作是一个子表达式/一个分组

2、捕获:

​ 把正则表达式中子表达式/分组匹配的内容,保存到内存中以数字编号或显式命名的组里,方便后面引用,从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推,组0代表的是整个正则式。

3、反向引用:

​ 圆括号的内容被捕获之后,可以在这个括号后被使用,从而写出一个比较实用的匹配模式,这个我们称为反向引用,这种引用既可以是在正则 表达式内部,也可以是在正则表达式外部,内部反向引用**\\分组号**,外部反向引用**$分组号**

例子(反向引用):

匹配两个连续的数字:

//匹配两个连续相等的数字
String content = "123455 asc66 ssw88";
String RegStr = "(\\d)\\1";
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
    System.out.println("find: "+matcher.group(0));
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-afKPmYyR-1651672474706)(C:\Users\松直君\AppData\Roaming\Typora\typora-user-images\image-20220504210142356.png)]

匹配多个连续的数字:使用{数字}来增加反向引用的数量

//匹配5个连续相同的数字
String content = "155555 asc66666 ssw88";
String RegStr = "(\\d)\\1{4}";

在这里插入图片描述

反向引用分组内容:

//匹配个位与千位相同,十位与百位相同的数字
String content = "15445 asc6776 ssw8877";
String RegStr = "(\\d)(\\d)\\2\\1";

在这里插入图片描述

例子2(去掉结巴语):

首先去掉…

//去掉结巴语,去掉连续重复的汉字,去掉...
String content = "我我...要学学学学...编程";
Pattern pattern = Pattern.compile("\\.");
Matcher matcher = pattern.matcher(content);
content = matcher.replaceAll("");
System.out.println("content= "+content);

然后去掉重复的汉字:这里利用外部的反向引用$1

pattern = Pattern.compile("(.)\\1+");
matcher = pattern.matcher(content);
content = matcher.replaceAll("$1");
System.out.println("content= "+content);

这里的话可以使用一句话进行处理:

content = Pattern.compile("(.)\\1+").matcher(content).replaceAll("$1");
System.out.println("content = "+content);

这里表达的思路就是,获取重复子串的第一个字,使用第一个字去替换剩下的重复的整个子串。

八、在String类中使用正则表达式:

替换:

String 类public String replaceAll(String regex,String replacement){}

//把windows1.0和windows2.0替换成windows
String s = "windows1.0、windows2.0,";
s = s.replaceAll("windows1\\.0|windows2\\.0","windows");
System.out.println(s);

判断:

String类 public bollean matches(String regex){}

//验证以137 138开头的手机号码
String s = "13699998866";
if(s.matches("1(38|39)\\d{8}")){
    System.out.println("验证成功!");
}else{
    System.out.println("验证失败!");
}

//验证以137 138开头的手机号码
String s = "13899998866";
if(s.matches("1(38|39)\\d{8}")){
    System.out.println("验证成功!");
}else{
    System.out.println("验证失败!");
}

分割:

String类 public String[] split(String regex){}

//按照~-#或者数字来分割字符串
String s = "back~to-home9,#OK!";
String[] oks = s.split("#|-|~|\\d+");
for (String ss:oks) {
    System.out.println(ss);
}

参考视频:b站韩顺平

【韩顺平讲Java】Java 正则表达式专题 -正则 正则表达式 元字符 限定符 Pattern Matcher 分组 捕获 反向引用等_哔哩哔哩_bilibili
1672474710)]

(https://www.bilibili.com/video/BV1Eq4y1E79W?p=1)


  1. \\d{3}相当于\\d\\d\\d其中{3}表示一共有三个前面这样的字符串,(\\d)?代表含有0个或者是1个\\d这样的数字字符串 ↩︎

  2. 2
    [^ 0-9a-zA-Z_]: [^0-9a-zA-Z_] ↩︎ ↩︎

  3. (\\d)*代表代表含有0个或者是n个\\d这样的数字字符串 ↩︎

  4. 前面有三个数字,后面有由数字、大小写字母字符组成的长度为4的字符串 ↩︎

  5. 中间的+代表一个到多个\\W字符串 ↩︎

掌握Java正则表达式,提升字符串匹配与处理能力 本文深入探讨了Java中的正则表达式,包括量词分类、转义元字符的使用、Pattern类和Matcher类的使用方法。通过实例,详细介绍了如何编译正则表达式、执行匹配、分割字符串以及连续匹配等高级功能。 阅读详情

相关推荐

掌握正则表达式:字符串分割与数据验证

本文详细探讨了Java中字符串、字符及正则表达式的处理方法。通过实例演示了如何使用String类的split方法来分割字符串,以及如何通过正则表达式对输入数据进行格式验证。文章中通过代码示例展示了正则表达式在字符串分割、数据验证以及替换操作中的强大功能,强调了正则表达式的灵活性和应用广泛性。

weixin_35391606的博客 1037

Java中的正则表达式 regex

常用类解析:正则表达式 regex前言一、正则表达式二、匹配规则 前言     正则表达式不仅仅是Java的技术,在任何一门编程语言中都会存在,是一种通用的IT技术,其理念和用法在任何编程语言中基本一致,除了有一些由于语言不同而导致的一些语法不同正则表达式,主要用于匹配(查找 替换 计数)字符串中的数据的,也叫做文本匹配技术。 一、正则表达式     经常会需要编写代码来验证用户输人,比如验证输人是否是一个数字,是否是一个全部小写的字符串,或者社会安全号。如何编写这种类型的代码呢?一个简单而有效的做法是使用

YING—country的博客 7122

Java正则表达式与字符串处理的深度解析

本文详细探讨了Java中正则表达式的使用、String类的操作方法以及Matcher和Pattern类的应用。通过实例代码,展示了如何使用这些类和方法来实现字符串匹配、替换和分词等操作。文章也强调了在正则表达式中正确转义特殊字符的重要性,并通过编程练习题来加深理解和应用。

weixin_35391606的博客 436

正则表达式匹配字符串中的数字 Java

我整理的一些关于【Git】的项目学习资料(附讲解~~)和大家一起分享、学习一下:https://d.51cto.com/xltfov正则表达式匹配字符串中的数字:Java 示例 在编程中,我们常常需要从字符串中提取出数字信息。正则表达式(Regular Expression,简称 Regex)是一种强大的工具,它允许我们...

weixin_35182625的博客 415

掌握Java中的字符串分割技术

正则表达式的核心能力来自于其丰富的操作符,以下是一些常用的正则表达式符号及其功能::匹配除换行符以外的任意单个字符。:匹配前一个字符0次或多次。:匹配前一个字符1次或多次。?:匹配前一个字符0次或1次。{n}:匹配前一个字符恰好n次。{n,}:匹配前一个字符至少n次。{n,m}:匹配前一个字符至少n次,但不超过m次。[abc]:匹配方括号内的任意一个字符。:匹配输入字符串的开始位置。:匹配输入字符串的结束位置。

weixin_33628677的博客 1110

掌握正则表达式:字符串匹配与处理的艺术

本文详细探讨了正则表达式在字符串匹配中的应用,包括各种匹配模式的使用及效果,以及如何利用Java中的Pattern和Matcher类实现复杂的文本处理逻辑。通过具体代码示例和输出结果,揭示了正则表达式的强大功能和灵活性。

weixin_36431145的博客 535

正则表达式经典实例PDF资源下载介绍:掌握文本处理利器,提升编程效率

正则表达式经典实例PDF资源下载介绍:掌握文本处理利器,提升编程效率 【下载地址】正则表达式经典实例PDF资源下载介绍 《正则表达式经典实例》是一本深入浅出的正则表达式实用教程,由高瓦特斯与利维森合著,郭耀翻译。本书通过100多个经典实例,详细讲解了正则表达式的基本原理和高级技巧,并涵盖了C#、Java、JavaScri...

gitblog_06738的博客 953

win10+conda+pytorch-gpu安装

pytorch 官网上只有linux和Mac的程序包,没有windows系统的,但是windows系统还是可以用pytorch的。  github: https://github.com/peterjc123/pytorch-scripts 首先要安装anaconda: 推荐清华镜像 https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ ...

一摩尔自由的博客 1万+

Java语言的字符串处理

字符串处理在Java编程中是一个重要的主题。通过学习Java中的字符串处理技巧,不仅能够提高代码的可读性和可维护性,还能在需要时有效地操作和处理字符串数据。在实际开发中,根据不同场景选择合适的字符串类和处理方法,将能够显著提高程序的性能和效率。

2501_90168220的博客 311

TM1650数码管驱动芯片

简介 TM1650是一款国产4位共阴数码管驱动芯片,它还带有矩阵按键扫码功能。它的基本参数如下: 工作电压:3~5V 数码管驱动模式:8段x4位共阴数码管 矩阵按键驱动模式:7x4矩阵按键,不支持组合键 通信接口:类IIC,使用了IIC相同的时序,但没有完全遵守IIC的协议,不带从机地址 引脚定义 SCL:串行通信时钟线 SDA:串行通信数据线 做数码管驱动使用时 DIGx:数码管的位选引脚,灌电流驱动,最大可吸收150mA电流 A~DP:数码管的段驱动引脚,拉电流驱动,最大可输出25m

luliplus的博客 4万+

Allegro File菜单实战指南:从导入网表到导出BOM的完整流程

PCB设计离不开对EDA软件菜单体系的深入理解。在Cadence Allegro中,File菜单是数据流转的中枢,它不仅是新建、打开、保存的基础入口,更是连接原理图与版图、设计与制造的关键桥梁。工程师常遇到的“导入网表报错”“导出BOM为空”“板框不闭合”等高频问题,大多源于对File菜单中Import与Export功能的理解不到位。从基础概念出发,先厘清Import(网表、DXF、IPC)与Export(BOM、ODB++、DXF)的工作原理,再结合版本兼容、封装库路径、单位设置等工程细节,即可构建完整的

weixin_32950759的博客 296

java的正则表达式

Java 中的正则表达式是一种强大而灵活的文本匹配方案,可用于检索、替换和匹配文本。正则表达式是一个字符串模式,它规定了要匹配哪些字符或字符序列。在 Java 中,正则表达式由 java.util.regex 包提供支持,主要使用 Pattern 和 Matcher 两个类来处理。Java 的正则表达式由各种字符和字符类组成,它们可以与输入文本进行匹配。该正则表达式是由多个字符和字符类组成,按顺序匹配输入文本。

wokeai1999的博客 989

实战指南:用Python实现ONVIF WS-Discovery设备发现(附完整代码)

本文提供了一份详细的实战指南,介绍如何使用Python实现基于ONVIF标准的WS-Discovery设备发现协议。文章深入解析了协议原理、网络通信模型,并提供了完整的代码实现,帮助开发者快速构建智能安防和物联网应用中的设备自动发现工具,有效提升网络设备集成与管理的效率。

chair的专栏 1114

java 正则表达式进行分割

使用Java正则表达式进行字符串分割 正则表达式是处理字符串的重要工具,能够有效地将字符串分割成更小的部分。本篇文章将指导你如何在Java中利用正则表达式进行字符串的分割。我们会通过一个详细的步骤流程、必要的代码实现以及充分的解释来确保你能完全掌握这一内容。 流程概述 在实现Java正则表达式分割的过程中,我们可以按照下表...

weixin_34220317的博客 579

别再乱调了!Zygo MetroPro软件滤波功能保姆级指南,从均值到鲁棒高斯样条一次讲清

本文深入解析Zygo MetroPro软件的滤波功能,从均值滤波到鲁棒高斯样条等九种算法,帮助用户根据测量对象特性选择最佳滤波组合。通过真实工业案例和参数配置指南,提升光学测量数据的准确性和效率,特别适用于硅晶圆、光学镜片等精密测量场景。

weixin_30888413的博客 156

2026年7月19日 从可插拔到共封装:技术路线研究报告

AI 算力的爆发正在重写数据中心光互连的技术路线。本报告对当前并存的四代光互连架构——

weixin_51184047的博客 587

如何使用Java中的正则表达式进行字符串匹配和替换?

在Java中,你可以通过以下步骤来实现自定义异常类:首先,你需要定义一个新的类,它必须从Exception或其子类(例如或)中继承。这个新的类将作为你的自定义异常类。以下是一个简单的示例,定义了一个名为// 自定义异常类的构造函数这个自定义异常类包含一个构造函数,该构造函数接收一个字符串参数(一个消息),并将该消息传递给,这将创建一个新的Exception对象。");这将在控制台输出 “Something went wrong!当你的代码遇到这个异常时,它将被捕获并传递给调用它的代码。你可以使用。

WangYaolove1314的博客 1512

【StarRocks】-- DATETIME 与 TIMESTAMP 区别详解

本文详细解析了StarRocks中DATETIME/DATETIMEV2与TIMESTAMP的区别及使用场景。DATETIME系列存储人类可读时间,不携带时区;TIMESTAMP实际指Unix时间戳,建议用BIGINT存储。关键差异包括:精度选择(DATETIMEV2支持微秒级)、时区处理(仅函数计算时影响)、存储方式等。针对不同场景提供选型建议:单时区展示用DATETIMEV2,跨时区计算用BIGINT存储Epoch。特别强调与MySQL迁移时的注意事项,并给出常见问题解决方案和最佳实践清单,包括统一入口

欢迎来到我的博客,一起探索代码里的世界! 499

java正则表达式教程

什么是正则表达式:正则表达式是一种用来描述字符串模式的语法。在 Java 中,正则表达式通常是一个字符串,它由普通字符(例如字母、数字、标点符号等)和特殊字符(称为元字符)组成。这些特殊字符可以表示一些模式,例如匹配数字、字母、空格等。正则表达式的作用::可以使用正则表达式在文本中查找特定的模式或子字符串。:可以使用正则表达式验证输入字符串是否符合特定的格式,例如电子邮件地址、手机号码等。:可以使用正则表达式替换文本中匹配的部分为指定的字符串。

2202_75569688的博客 2522

apollo自动驾驶进阶学习之:如何实现施工路段限速绕行及其参数调试

首先需要理解Planning模块是基于Scenario、Stage、Task这样的层次来进行的,即场景->步骤->具体的决策方法。Apollo可以应对自动驾驶所面临的不同道路场景,都是通过Scenario统一注册与管理。Scenario通过一个有限状态机来判断选择当前行车场景,每个Scenario下又有多个Stage,指当前场景下需要执行的粗略步骤。.........

qq_41593516的博客 6598

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

在Java中实现高效的字符串处理

本文深入探讨了Java中字符串的基本操作、StringBuilder与StringBuffer的使用、正则表达式的应用以及字符串性能优化的策略。在Java中,如果需要频繁地对字符串进行修改操作(如拼接、插入、替换等),推荐使用StringBuilder(非线程安全)或StringBuffer(线程安全)来提升效率。在Java中,字符串是一种基本的数据类型,也是编程中最常用的数据类型之一。Java提供了丰富的API来处理字符串,包括字符串的创建、连接、比较、查找等操作。

技术研究中心 288

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【Java教程】Day13-06 正则表达式:字符串分割、搜索与替换

正则表达式在 Java 中提供了强大的字符串处理能力,允许我们对字符串进行灵活的操作,如分割、搜索和替换等。本文将通过实例详细讲解如何在 Java 中使用正则表达式实现这些功能,帮助你高效处理字符串数据。

max202011161630的博客 789

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Java正则表达式:强大的字符串匹配工具

然而,在使用正则表达式时,需要理解其基础概念、掌握常见的应用场景,并注意性能优化和特殊字符的转义。本文将介绍Java正则表达式的基本概念、语法和常见应用场景,以及一些实用技巧,帮助开发人员充分发挥正则表达式在字符串处理中的作用。转义字符:一些特殊字符在正则表达式中具有特殊的含义,如果要匹配这些字符本身,需要使用转义字符进行转义,如"."表示匹配点字符。可以使用非贪婪匹配模式来只匹配最小的字符片段。边界匹配:通过使用边界匹配元字符,如^表示行的开头,$表示行的结尾,可以限定匹配发生的位置,实现更精确的匹配。

sun13047140038的博客 604

java用Scanner的正则表达式分割字符串

使用正则表达式或者Scanner对象,能够以复杂的方式分割一个字符串,而这个对于StringTokenizer来说很困难,基本情况下,StringTokenizer可以废弃不用了。 import java.util.Scanner; import java.util.StringTokenizer; public class StringSplitTest { public stati...

每天进步一点点儿 2064

精通正则表达式第三版简体中文版下载仓库:掌握文本处理利器,提升工作效率

精通正则表达式第三版简体中文版下载仓库:掌握文本处理利器,提升工作效率 【下载地址】精通正则表达式第三版简体中文版下载仓库 《精通正则表达式(第三版)简体中文版》是一本全面深入的正则表达式学习指南,适合各类开发者。本书从基础概念入手,逐步深入,详细讲解了正则表达式在多种编程语言中的实际应用,涵盖了文本处理、数据挖掘等实用...

gitblog_06762的博客 396

Generex:正则表达式生成器的利器

Generex:正则表达式生成器的利器 是一个创新的Java库,用于根据给定的正则表达式动态生成匹配该模式的随机字符串。如果你在进行数据测试、安全审计或者需要大量模拟数据时,这个项目将是你的好帮手。 项目简介 Generex的核心目标是简化生成符合特定规则的字符串的过程。通过解析输入的正则表达式,它能够创建出无限数量的独特字符串,这对于自动化测试和数据填充特别有用。开发者不再需要手动构造这些字符串...

gitblog_00034的博客 665
下一篇: Spring-IOC
吊云
博客等级 码龄6年 73粉丝 10原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值