前言:
Java提供正则表达式技术,专门用于处理文本问题。
简单的说:正则表达式(regular expression) 是对字符串执行模式匹配的技术。
一个正则表达式,就是用某种模式去匹配字符串的一个公式。
一、下面先看一下正则表达式的基本用法:
public class Regexp {
public static void main(String[] args) {
String content = "1995年,互联网的蓬勃发展给了Oak机会。业界为了使死板、单调的静态网页能够“灵活”起来,急需一种软件技术来开发一种程序,这种程序可以通过网络传播并且能够跨平台运行。于是,世界各大IT企业为此纷纷投入了大量的人力、物力和财力。这个时候,Sun公司想起了那个被搁置起来很久的Oak,并且重新审视了那个用软件编写的试验平台,由于它是按照嵌入式系统硬件平台体系结构进行编写的,所以非常小,特别适用于网络上的传输系统,而Oak也是一种精简的语言,程序非常小,适合在网络上传输。Sun公司首先推出了可以嵌入网页并且可以随同网页在网络上传输的Applet(Applet是一种将小程序嵌入到网页中进行执行的技术)" +
",并将Oak更名为Java(在申请注册商标时,发现Oak已经被人使用了," +
"再想了一系列名字之后,最终,使用了提议者在喝一杯Java咖啡时无意提到的Java词语)。" +
"5月23日,Sun公司在Sun world会议上正式发布Java和HotJava浏览器。" +
"IBM、Apple、DEC、Adobe、HP、Oracle、Netscape和微软等各大公司都纷纷停止了自己的相关开发项目" +
",竞相购买了Java使用许可证,并为自己的产品开发了相应的Java平台。";
// Pattern pattern = Pattern.compile("[a-zA-Z]+"); //提取文章中所有的英文单词
Pattern pattern = Pattern.compile("[0-9]+"); //提取文章中所有的数字
// Pattern pattern = Pattern.compile("([0-9]+)|([a-zA-Z]+)"); //提取文章中所有的英文单词和数字
//创建匹配器
//说明:创建匹配器matcher,按照正则表达式的规则,去匹配content中的字符串
Matcher matcher = pattern.matcher(content);
//理解:matcher匹配器按照pattern(模式/样式),到content文本中去匹配,找到就返回true,否则就返回false
while (matcher.find()) {
//匹配内容文本,放到m.group(0)
System.out.println("找到:" + matcher.group(0));
}
}
}
输出文本中所有的数字:
二、正则表达式语法
介绍:如果想要灵活的运用表达式,必须了解其中各种元字符的功能,元字符从功能上大致分为:
- 限定符
- 选择匹配符
- 分组组合和反向引用符
- 特殊字符
- 字符匹配符
- 定位符
1.之后首先我们说一下,元字符中的转义符或者说是转义号\ \
在我们使用正则表达式去检索某些特殊字符的时候,需要用到转义符号,否则检索不到结果。
案例代码如下:
public class Regexp02 {
public static void main(String[] args) {
String content = "(abc$(abc";
String regStr = "\\(";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println("找到:" + matcher.group(0));
}
}
}
输出结果:
需要用到的转义符号的字符有以下:. * + ( ) $ / \ ? [ ] ^ { }
2 .接着我们来看字符匹配符都有哪些?
具体的意思也已经给出,大家可以体会一下
下面通过具体的代码来演示一下,具体注释已经在代码中给出了
public class Regexp03 {
public static void main(String[] args) {
String content = "a11c8 _abcABC@";
System.out.println(content);
// String regStr = "[a-z]"; //匹配a-z之间任意一个字符
// String regStr = "[A-Z]";//匹配A-Z之间任意一个字符
// String regStr = "abc"; //匹配abc字符串[默认区分大小写的]
// String regStr = "(?i)abc"; //匹配abc字符串[不区分大小写的]
// String regStr = "[0-9]"; //匹配0-9之间任意一个字符
// String regStr = "[^a-z]"; //匹配不在a-z之间任意一个字符
// String regStr = "[^0-9]";//匹配不在0-9之间任意一个字符
// String regStr = "[abcd]";//匹配在abcd中任意一个字符
// String regStr = "\\D"; //匹配不在0-9的任意一个字符
// String regStr = "\\w"; //匹配 任意英文字母,数字,下划线
// String regStr = "\\W"; //匹配 等价于[^a-zA-Z0-9_]
// String regStr = "\\s"; //匹配 任何空白字符(空格,制表符(就是按下tab键的一个空格))
// String regStr = "\\S"; //匹配 任何非空白字符,和\\s刚好相反
String regStr = "."; //匹配除\n 之外的所有字符,如果要匹配.本身则需要使用\\.
//说明:当创建Pattern对象时,指定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));
}
}
}
3 .元字符-选择匹配符
具体案例代码如下,便于理解:
public class Regexp04 {
public static void main(String[] args) {
String content = "ha你好 哈 蛤 Java";
String regStr = "ha|蛤|哈|Java";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println("找到:" + matcher.group(0));
}
}
}
输出结果:
4 .元字符-限定符
用于指定其前面的字符和组合项连续出现多少次
下面通过代码更好的理解一下:
public class Regexp05 {
public static void main(String[] args) {
String content = "a21111111aaaaaahello";
// String regStr = "a{3}"; //表示匹配aaa
// String regStr = "1{4}"; //表示匹配1111
// String regStr = "\\d{2}"; //表示匹配 2位的任意数字字符
//细节:java匹配默认是贪婪匹配,即尽可能匹配多的
// String regStr = "a{3,4}"; //表示匹配 aaa或者aaaa
// String regStr = "1{4,5}"; //表示匹配 1111或者11111
// String regStr = "\\d{2,5}"; //表示匹配 两位数或者三位数,四位数,五位数
// String regStr = "1+"; //匹配一个1或者多个1
// String regStr = "\\d+"; //匹配一个数字或者多个数字
// String regStr = "1*"; //匹配0个1或者多个1
//演示?的使用,遵守贪婪匹配
String regStr = "a1?"; //匹配 a 或者 a1
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println("找到:" + matcher.group(0));
}
}
}
5 .元字符-定位符
定位符:规定要匹配的字符串出现的位置,比如在字符串的开始还是在结束的位置。
下面通过代码更好的理解一下:
/**
* 演示定位符的使用
*/
public class Regexp06 {
public static void main(String[] args) {
String content = "helloworld hihello youhellou";
// String content = "123-abc";
// String regStr = "^[0-9]+[a-z]*"; //匹配 以至少1个数字开头,后接任意个小写字母的字符串
// String regStr = "^[0-9]+[a-z]+$"; //匹配 以至少1个数字开头,必须以至少一个小写字母结束
// String regStr = "^[0-9]+\\-[a-z]+$"; //匹配 以至少1个数字开头,必须以至少一个小写字母结束,同时中间有一个-
//表示匹配边界的hello(这里的边界是指:被匹配的字符串最后,也可以是空格的子字符串的后面)
// String regStr = "hello\\b";
//和\\b的含义刚好相反
String regStr = "hello\\B";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while (matcher.find()){
System.out.println("找到:"+matcher.group(0));
}
}
}
三、正则表达式的分组
1 .捕获分组
下面通过代码更好的理解一下:
public class Regexp07 {
public static void main(String[] args) {
String content = "helloJava hi2821 yes2022";
//下面是非命名分组:
//说明:
//1.matcher.group(0)得到匹配到的字符串
//2.matcher.group(1)得到匹配到的字符串的第一个分组内容
//3.matcher.group(2)得到匹配到的字符串的第二个分组内容
//非命名捕获
// String regStr = "(\\d\\d)(\\d\\d)"; //匹配4个数字的字符串
//命名分组:即可以给分组取名
String regStr = "(?<g1>\\d\\d)(?<g2>\\d\\d)";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println("找到:" + matcher.group(0));
System.out.println("第一个分组内容:" + matcher.group(1));
System.out.println("第一个分组内容[通过组名]:" + matcher.group("g1"));
System.out.println("第二个分组内容:" + matcher.group(2));
System.out.println("第二个分组内容[通过组名]:" + matcher.group("g2"));
}
}
}
输出结果如下:
2 .非捕获分组
下面通过代码更好的理解一下:
public class Regexp08 {
public static void main(String[] args) {
String content = "程序员Android程序员Hello Hi程序员Java程序员 HI程序员Python程序员";
// String regStr = "Android程序员|Java程序员|Python程序员";
//上面的写法可以等价为非捕获分组,注意:不能matcher.group(1)
// String regStr = "程序员(?:Android|Java|Python)";
//找到程序员这个关键字,但是只要求查找程序员Android,程序员Java
//下面是非捕获分组,注意:不能matcher.group(1)
// String regStr = "程序员(?=Android|Java)";
//找到程序员这个关键字,但是只要求 不查找程序员Android,程序员Java
//下面是非捕获分组,注意:不能matcher.group(1)
String regStr = "程序员(?!Android|Java)";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println("找到:" + matcher.group(0));
}
}
}
最后一个输出结果为:
3 .非贪婪匹配
public class Regexp09 {
public static void main(String[] args) {
String content = "hello111111 ok";
//默认是贪婪匹配
// String regStr = "\\d+";
//非贪婪匹配
String regStr = "\\d+?";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println("找到:" + matcher.group(0));
}
}
}
输出结果:
以上常用的正则表达式元字符就讲解完了,如果有不当之处,还望各位加以指正~