一:正则表达式
1.1 正则表达式的介绍:
- 一个正则表达式,就是用某种模式去匹配字符串的一个公式。(处理文本)
- 正则表达式不是只有Java才有,实际上很多编程语言都支持正则表达式进行字符串操作。
1.2 正则表达式的代码实现(不考虑分组):
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegTheory {
/*
分析正则表达式的底层实现
*/
public static void main(String[] args) {
String content="1998年12月8日,第二代Java平台的企业版J2EE发布。1999年6月,Sun公司发布了第二代Java平台(简称为Java2)的3个版本:J2ME(Java2 Micro Edition,Java2平台的微型版),应用于移动、无线及有限资源的环境;J2SE(Java 2 Standard Edition,Java 2平台的标准版),应用于桌面环境;J2EE(Java 2Enterprise Edition,Java 2平台的企业版),应用于基于Java的应用服务器。9889Java 2平台的发布,是Java发展过程中最重要的一个里程碑,标志着Java的应用开始普及。3443";
//目标:匹配所有四个数字
//说明:
//1. \\d表示一个任意的数字,在这里就是匹配四个数字
String regStr="\\d\\d\\d\\d";
//2. 创建模式对象【即正则表达式对象】
Pattern pattern=Pattern.compile(regStr);
//3. 创建匹配器
//说明:创建匹配器matcher,按照正则表达式的规则去匹配content字符串
Matcher matcher=pattern.matcher(content);
//4.开始匹配
/*
matcher.find() 完成任务
1.根据指定的规则,定位满足规则的子字符串(比如1998)
2.找到后,将子字符串的开始的索引记录到matcher对象的属性 int[] groups;
groups[0]=0,把该子字符串的结束的索引+1的值记录到groups[1]=4
3.同时记录oldLast的值为子字符串的结束的索引+1的值即4,即下次执行find时,就从4开始匹配
*/
/*
matcher.group(0)分析:
源码:
public String group(int group) {
if (first < 0)
throw new IllegalStateException("No match found");
if (group < 0 || group > groupCount())
throw new IndexOutOfBoundsException("No group " + group);
if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
return null;
return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
}
当matcher.group(int group)中的参数为0时,根据groups[0]=0和groups[1]=4的记录的位置,从content开始截取子字符串返回,就是[0,4)---包含索引开始,不包含索引结尾
*/
while (matcher.find()){
System.out.println("找到"+matcher.group(0));
}
}
}
1.3 正则表达式的代码实现(考虑分组):
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegTheory {
/*
分析正则表达式的底层实现
*/
public static void main(String[] args) {
String content="1998年12月8日,第二代Java平台的企业版J2EE发布。1999年6月,Sun公司发布了第二代Java平台(简称为Java2)的3个版本:J2ME(Java2 Micro Edition,Java2平台的微型版),应用于移动、无线及有限资源的环境;J2SE(Java 2 Standard Edition,Java 2平台的标准版),应用于桌面环境;J2EE(Java 2Enterprise Edition,Java 2平台的企业版),应用于基于Java的应用服务器。9889Java 2平台的发布,是Java发展过程中最重要的一个里程碑,标志着Java的应用开始普及。3443";
//目标:匹配所有四个数字
//说明:
//1. \\d表示一个任意的数字,在这里就是匹配四个数字
String regStr="(\\d\\d)(\\d\\d)";
//2. 创建模式对象【即正则表达式对象】
Pattern pattern=Pattern.compile(regStr);
//3. 创建匹配器
//说明:创建匹配器matcher,按照正则表达式的规则去匹配content字符串
Matcher matcher=pattern.matcher(content);
//4.开始匹配
/*
matcher.find() 完成任务------(考虑分组)
什么是分组,比如(/d/d)(/d/d),正则表达式中有()表示分组,第一个()表示第一组,第二个()表示第二组...(依次类推)
1. 根据指定的规则,定位满足规则的子字符串(比如(19)(98))
2. 找到后,将子字符串的开始的索引记录到matcher对象的属性int[] groups
2.1 groups[0]=0,把该子字符串的结束的索引+1的值记录到groups[1]=4
2.2 记录一组()匹配到的字符串groups[2]=0 groups[3]=2
2.3 记录二组()匹配到的字符串groups[2]=2 groups[3]=4
2.4 有更多的分组,依次类推
3.同时记录oldLast的值为子字符串的结束的索引+1的值即4,即下次执行find时,就从4开始匹配
*/
/*
matcher.group(0)分析:
源码:
public String group(int group) {
if (first < 0)
throw new IllegalStateException("No match found");
if (group < 0 || group > groupCount())
throw new IndexOutOfBoundsException("No group " + group);
if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
return null;
return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
}
当matcher.group(int group)中的参数为0时,根据groups[0]=0和groups[1]=4的记录的位置,从content开始截取子字符串返回,就是[0,4)---包含索引开始,不包含索引结尾
*/
while (matcher.find()){
//小结
//1.如果正则表达式有()即分组
//2.取出匹配的字符串规则如下:
//3.group(0)表示匹配到的子字符串
//4.group(1)表示匹配到的子字符串中的第一组字符串
//5.group(2)表示匹配到的子字符串中的第二组字符串
//6....但是分组的数不能越界。
System.out.println("找到"+matcher.group(0));
System.out.println("第1组()匹配的值="+matcher.group(1));
System.out.println("第2组()匹配的值="+matcher.group(2));
}
}
}
二:正则表达式的语法
2.1 基本介绍:
如果想要灵活的运用正则表达式,必须了解其中各种元字符的功能,元字符从功能上大致分为:
- 限定符
- 选择匹配符
- 分组组合和反向引用符
- 特殊字符
- 字符匹配符
- 定位符
2.2 元字符(Metacharacter)
2.2.1 元字符-转义符 \\:
(在Java的正则表达式中,两个\\代表其他语言中的一个\)
需要用到转义符号的字符有以下:. + ( ) $ / \ ? [ ] ^ { }
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegEcp02 {
public static void main(String[] args) {
String content="abc$(abc(123(";
//匹配(
String regStr="\\("; //需要使用转义字符
Pattern pattern=Pattern.compile(regStr);
Matcher matcher=pattern.matcher(content);
while (matcher.find()){
System.out.println("找到"+matcher.group(0));
}
}
}
2.2.2 元字符-字符匹配符:
字符匹配符的应用实例:
1. [a-z]说明:[a-z]表示可以匹配a-z中任意一个字符。
2.Java正则表达式默认是区分字母大小写的,如何实现不区分大小写
- (?i)abc表示abc都不区分大小写
- a(?i)bc表示bc不区分大小写
- a((?i)b)c表示只有b不区分大小写
- Pattern pattern=Pattern.compile(regEx,Pattern.CASE_INSENSITIVE);
3.[^a-z]说明:[^a-z]表示可以匹配不是a-z中的任意一个字符
4.\\d表示可以匹配0-9的任意一个数字,相当于[0-9]
5.\\D表示可以匹配不是0-9中的任意一个数,相当于[^0-9]
6.\\w匹配任意英文字符,数字和下划线,相当于[a-zA-Z0-9]
7.\\W相当于[^a-zA-Z0-9]是\w刚好相反
8.\\s匹配任何空白字符(空格、制表符等)
9.\\S匹配任何非空白字符,和\s刚好相反
10. (.)匹配出\n之外的所有字符,如果要匹配,本身则需要使用\\
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegExp03 {
public static void main(String[] args) {
String content="a11c8abcABC";
/*
java正则表达式默认区分大小写
*/
//String regStr="[a-z]";//1.匹配到a-z任意一个字符
//String regStr="[A-Z]";//2.匹配到A-Z任意一个字符
//String regStr="(?i)abc";//3.匹配abc字符串【不区分大小写】
String regStr="[^a-z]{2}";//5.匹配不在a-z之间任意一个字符
Pattern pattern=Pattern.compile(regStr);
//4.当创建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));
}
}
}
2.2.3 元字符-选择匹配符:
在匹配某个字符串的时候是选择性的,即:既可以匹配这个,又可以匹配那个,这是你需要用到选择匹配符。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegExp04 {
public static void main(String[] args) {
/*
选择匹配符
*/
String content="周 jia jiaX 1221321abc zhou ABC";
String RegStr="周|zhou";
Pattern pattern=Pattern.compile(RegStr);
Matcher matcher=pattern.matcher(content);
while (matcher.find()){
System.out.println("找到 "+matcher.group(0));
}
}
}
2.2.3 元字符-限定符:
用于指定其前面的字符和组合项连续出现多少次
注意:Java匹配默认贪婪匹配,即尽可能匹配多的
例如:"a{3,4}",Java优先匹配aaaa,然后匹配aaa
2.2.4 元字符-定位符:
定位符,规定要匹配的字符串出现的位置,比如在字符串的开始还是在结束的位置,这个也是相当有用的。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegExp05 {
public static void main(String[] args) {
/*
定位符
*/
// String content = "123周 123jia jiaX 122zhou1321abc zhou ABC abcabc123abc 123zhou";
String content = "123zhouabczhou 123zhou";
// String RegStr = "^[0-9]+[a-z]*";//以至少一个数字开头(字符串的开头),后接任意个小写字母的字符串
// String RegStr = "^[0-9]+[a-z]+$"; //以至少一个数字开头,必须以至少一个小写字母结束
//String RegStr="zhou\\b"; //表示匹配边界的zhou[这里的边界是指:被匹配的字符串最后],也可以是空格的字符串的后面
String RegStr="zhou\\B"; //表示匹配非边界的zhou
Pattern pattern = Pattern.compile(RegStr);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println("找到 " + matcher.group(0));
}
}
}
2.3 分组:
2.3.1:常见分组:
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegExp06 {
/*
分组
*/
public static void main(String[] args) {
String content="abc1234def5678";
//String regStr="(\\d\\d)(\\d\\d)";//匹配4个数字的字符串
//命名分组:即可以给分组取名
String regStr="(?<g1>\\d\\d)(?<g2>\\d\\d)";//匹配4个数字的字符串
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(2));//得到匹配到的字符串的第二个分组内容
}
*/
while (matcher.find()){
System.out.println("找到="+matcher.group(0));
System.out.println("第一个分组内容[通过分组]="+matcher.group("g1"));
System.out.println("第二个分组内容[通过分组]="+matcher.group("g2"));
}
}
}
2.3.2 :特别分组:(非捕获分组)
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegExp07 {
/*
非捕获分组
*/
public static void main(String[] args) {
String content="zjx教育,zjx老师,zjx同学";
// String RegStr="zjx教育|zjx老师|zjx同学";
//上面写法可以等价非捕获分组,注意:不能 matcher.group(1)
// String RegStr="zjx(?:教育|老师|同学)";
//找到zjx这个关键字,但是要求只是找到zjx教育和zjx老师中的zjx
//String RegStr="zjx(?=教育|老师)";
String RegStr="zjx(?!同学)"; //取反,也可以的到这样的结果
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)); //这里会报错,因为是非捕获分组
}
*/
while (matcher.find()){
System.out.println("找到 "+matcher.group(0));
}
}
}
2.4 非贪婪匹配:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegExp08 {
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));
}
}
}