正则表达式
正则表达式是针对字符的比较,可以用来匹配,替换,提取信息等操作
1基本操作
1.1基本的匹配
//基本的匹配
//匹配: "." :任意字符
System.out.println("1a#".matches("..."));
//匹配数字:\d(数字1-9),\D(不是数字)
System.out.println("1a#".matches("\\d\\D\\D"));
//匹配空白字符:\s(空格和制表符等),\S(不为空格)
System.out.println("1 a 2".matches("\\S\\s\\S\\s\\S"));
//匹配基本字符:\w(基本字符),\W(非字符)
System.out.println("aZ!".matches("\\w\\w\\W"));
//区间匹配
//区间:[] ,[a-z]表示是否位于该区间,区分大小写
System.out.println("a".matches("[a-z]"));
System.out.println("a".matches("[A-Z]")); //false
//非区间:[^a-z],在区间里面加个"^"
System.out.println("a".matches("[^A-Z]"));
//
//&&(并且),||(或)
System.out.println("b".matches("[a-c&&d-f]")); //false,要在a-c,还要是在d-f
System.out.println("b".matches("[a-c||d-f]"));
1.2基本范围匹配
//基本的范围匹配
// ?:零次或一次
// *:零次或多次
// + :一次或多次
System.out.println("".matches("a?"));
System.out.println("aaaa".matches("a*"));
System.out.println("aaaa".matches("a+"));
//
// {n} :一定要出现n次
// {n,} :最少出现n次
// {n,m} :最少出现n次,最多出现m次
System.out.println("aaaa".matches("a{4}"));
System.out.println("aaaa".matches("a{2,}"));
System.out.println("aaaa".matches("a{1,4}"));
//
//边界
// ^ : 不在区间内[^],这个是匹配边界,是否是开头
// $ : 是否是结尾
System.out.println("1231asda13".matches("^123.*")); //以123开头后面有0个或多个任意字符
System.out.println("xcvx3453豆豆腐干".matches(".*豆腐干$")); //有0个或多个任意字符,一豆腐干结尾
//替换
//字符串中方法replaaceAll()
String str = "123asd456asd";
//将数字替换成*
System.out.println(str.replaceAll("\\d", "*")); //输出:***asd***asd
System.out.println(str.replaceAll("\\d+", "*"));//输出:*asd*asd
//将末尾的4位替换成*
System.out.println(str.replaceAll(".{4}$", "****"));//输出:
//案例:
//是否是电话号码,电话号码格式如:0791-3284569-01
//思路:1先是4个数字,然后一个-,在加7位数字,然后又一个-,最后还有两位数字
String strs = "0791-3284569-01";
strs.matches("\\d{4}-\\d{7}-\\d{2}");
2(Pattern与Matcher)
2.1 提取字符
Pattern:可以将正则表达式编译成Pattern对象,提高效率
Matcher:可以对匹配的字符进行操作
Matcher中的常用方法:find():试查找匹配成功的字符
group():提取匹配成功的数据,注意的是要在find()之后调用这个方法
start():返回匹配的成功开始位置
end():返回匹配成功的最后位置
例:
String str = "123-456-789";
//将正则表达式编译成Pattern对象,可以提高效率
Pattern p = Pattern.compile("\\d*"); //匹配所有的数字
//
Matcher m = p.matcher(str);
//将索引的指针重置
m.reset();
//提取匹配成功的字符
while(m.find()){ //1,找到与之匹配成功的就返回true,直到字符串结束
//用group(),获取匹配成功的字符,注意的是一定要在find之后调用这个方法
System.out.println(m.group()+"["+m.start()+","+m.end()+"]");
}
2.2将字符分组
用括号来分组,一个括号一个组
group(int):int参数分别获取不同组中的字符
栗子:
获取一组身份证号码,并分别提取身份证的出生地址码,出生日期码和检验码
//一组18位身份证号码(乱写的)
String str = "123456789987654125,852147896523652145,123456852132548958";
//使用括号进行分组
//先是6位的地址,在是8位的日期,最后4位的编号
Pattern p =Pattern.compile("(\\d{6})(\\d{8})(\\d{4})");
Matcher m = p.matcher(str);
//group()传入参数获取
while(m.find()){
//1就为第一组,对应第一个括号
System.out.println("出生地:"+m.group(1)+"-出生日期:"+m.group(2)+"-编号:"+m.group(3));
}
输出结果:
出生地:123456-出生日期:78998765-编号:4125
出生地:852147-出生日期:89652365-编号:2145
出生地:123456-出生日期:85213254-编号:8958
2.3贪婪和非贪婪
用?号来区分
先看个贪婪模的栗子:
//提取<a></a>之间的数据
String str = "<a>你好</a> <a>大家好</a>";
//
Pattern p = Pattern.compile("<a>(.*)</a>");
Matcher m = p.matcher(str);
//分别提取
while(m.find()){
System.out.println(m.group(1));
}
输出结果:你好</a><a>大家好
解析:贪婪模式会重头取到尾,中间的如果有与匹配的会忽率掉
所以需要非贪婪模式来精确提取
只要加个?号就可以,这个遇到与之匹配的就会提取,而不会重头取到尾
栗子:
//提取<a></a>之间的数据
String str = "<a>你好</a><a>大家好</a>";
//
//在要提取的表达式中加个?号
Pattern p = Pattern.compile("<a>(.*?)</a>");
Matcher m = p.matcher(str);
//分别提取
while(m.find()){
System.out.println(m.group(1));
}
输出结果:
你好
大家好