/*
* 正则表达式:符合一定规则的表达式
* 作用:用于专门操作字符串
* 特点:用一些特定的符号来表示代码的操作,简化书写
* 所以学习正则表达式就是学习一些特定的符号的使用
* 好处:可以简化对字符串的复杂操作
* 弊端:符号定义越多,正则越长,阅读性越差
*
* 具体操作功能:
* 1.匹配:String类中的matches()方法
* matches(String regex) 告知此字符串是否匹配给定的正则表达式。返回boolean类型的值
* matches()方法用规则匹配整个字符串,只要有一处不符合规则,就匹配结束,返回false
*
* 2.切割:String类中的split()方法
* 注意切割的时候尽量不要用正则表达式定义的特殊符号
* 如果要用则要转义一下,变成这样\\.因为如果只是".",它表示任意字符,如果用它切没有意义
*
* 3.替换:replaceAll()方法,还有replaceFirst()方法(此处没有列用法)
*
* 4.获取:将字符串中的符合规则的字串取出(注意参考JDK帮助文档中的Pattern和Matcher)
* 操作步骤:
* 1.将正则表达式封装成对象
* 2.让正则对象与要操作的字符串相关联
* 3.关联后,获取正则匹配引擎
* 4.通过引擎对符合规则的字串进行操作,比如取出
*/
package 类;
import java.util.regex.*;
public class 正则表达式 {
public static void main(String[] args) {
// TODO Auto-generated method stub
正则表达式 d = new 正则表达式();
d.getDemo();
System.out.println("--------------------------------------");
d.getMatcher();
System.out.println("--------------------------------------");
String str = "as12we344w542404y44333ew56djhsddog1424405isd3140465jfksgh40444445adbcja45gd";
//把字符串中所有的数字都替换成#
d.replaceAllDemo(str,"\\d","#");
System.out.println("--------------------------------------");
//把字符串中连续超过5个的替换成一个#
d.replaceAllDemo(str,"\\d{5,}","#");
System.out.println("--------------------------------------");
//将字符串中的叠词替换成#
String str1 = "asaaaafsgdkfaaaakdfgkkdfgjjsdfgdgg";
//两个相同的替换成一个#
d.replaceAllDemo(str1,"(.)\\1","#");
System.out.println("--------------------------------------");
//相同单词长度超过1的都替换一个#
d.replaceAllDemo(str1,"(.)\\1+","#");
System.out.println("--------------------------------------");
//将字符串中的叠词替换成单个的字母;例如:zzzz-->z;zz-->z;zzz-->z
//通过另外一个规则($1)获取组中的元素
d.replaceAllDemo(str1,"(.)\\1+","$1");
System.out.println("--------------------------------------");
/*
* 切割字符串,按照多种对应字符切割
* 下面代码提供了多种切割规则
* 除了需要转义的特殊字符,其他的字符采用相同的方式进行切割
* 例如可以把下面的逗号改成空格得到的结果相同
*/
//按照多个"\\"来切割
//注意如果表示"\"要用两个"\\"
//"\\\\"表示两个"\\"
d.splitDemo("c\\abc\\\\\\aa.txt","\\\\+");
System.out.println("--------------------------------------");
//按照多个点.来切割字符串
d.splitDemo("天.真...无.....邪","\\.+");
System.out.println("--------------------------------------");
//按照多个逗号来进行切割
d.splitDemo("天,真,,,,无,,,,,,,,,,,,邪",",+");
System.out.println("--------------------------------------");
//按照一个逗号来进行切割
d.splitDemo("天,真,无,邪",",+");
System.out.println("--------------------------------------");
/*
* 按照叠词切割字符串(叠词:前一个字符和后面一个相同,例如:aa,kk)
* 切割规则:
* 第二位要用第一位的结果,即第二位是第一位字符的再一次出现
* 第一位的结果被第二位重用
* 为了让规则的结果被重用,可以将规则封装成一个组,用()完成
* 组的出现都有编号,从1开始,
* 想要使用已有的组可以通过\n(n就是组的编号)的形式来获取
* 此时就表明第二位的结果和第一位一致
*
* ((())())像这种特殊的情况要判断有几组只需要判断有几个左括号
* 此时这种情况有四组,判断是第几组从左到右,第一个左括号是第一组,第二个左括号是第二组
* 依次类推即可(注意看JDK帮助文档)
*/
/*
* 注意:如果三个相同或者五个相同的在一块,则按照前面两个进行切割
* 如果说所有的相同的在一块都用来切割,在\\1后面加上一个加号
*/
d.splitDemo("sfaalkkdsffgjaaadodigssd", "(.)\\1");
System.out.println("--------------------------------------");
d.splitDemo("sfaalkkkdsffgjaaadodigssdaffffghdfffffd", "(.)\\1+");
System.out.println("--------------------------------------");
/*
* 如果说全部相同的时候,注意输出结果
* 如果相同的字符的个数是偶数,输出结果为0,这种情况没有意义
* 如果为奇数,会输出一大堆为空的字符串,由切割次数控制
*/
d.splitDemo("aaaaaaaaaaaaaaaaa", "(.)\\1");
System.out.println("--------------------------------------");
d.splitDemo("aaaaaaaaaaaaaaaaa", "(.)\\1+");
System.out.println("--------------------------------------");
//匹配手机号码
d.Tel();
//匹配QQ号码
d.QQ();
//匹配邮箱
d.Email();
}
public void getDemo() {
/*
* 找出由连续三个字母组成的单词
* 如果说要获取其他长度的字符串,只需要把匹配规则regStr中的{3}改为相对应的长度即可
*/
String str = "ming tiannn shi xing qi liu,bu zhi dao yao gan ma qu ne?";
String regStr = "\\b[a-z]{3}\\b";
//将规则封装成对象
Pattern p = Pattern.compile(regStr);
//让正则对象和要作用的字符串相关联,获取字符串对象
Matcher m = p.matcher(str);
// //find()方法用来将规则作用到字符串上,并进行符合规则的字符串查找
// boolean b = m.find();
// //判断是否匹配成功,是否找到
// System.out.println(b);
// //group()用来获取匹配后的结果
// System.out.println(m.group());
/*
* 利用循环实现
* 注意这种时候对于长度为4的字符,会输出前三个
* 这种时候引申出另一个知识点:单词的边界
* 即边界匹配器,通过改变匹配规则实现
* 修改之前的结果为
* min tia nnn shi xin liu zhi dao yao gan
* 此时把regStr修改为regStr = "\\b[a-z]{3}\\b";
* 修改之后的结果为
* shi liu zhi dao yao gan
*/
/*
* 里面有些东西需要特别注意
* 如果在find查找之前用mathcers进行匹配,根据匹配规则,返回的是false
* 因为 matches() 尝试将整个区域与模式匹配.此时的字符串长度不是4,而且存在不是小写字母的字符
* 接着指针所指的位置就会发生变化.由于前面的四个字符满足条件,所以一直往后查找,当查找到第四个位置(从第0个开始)的时候,不匹配
* 此时指针就停留在这个位置,当继续往后运行执行find()的时候,就接着从第四个位置开始
* 此时前面的4个字符就不会再进行判断,会出现错误情况,不防将find()前面的输出语句执行一次观察结果
* 如果将匹配规则里面判断字符的长度改为4,即{3}-->{4},结果会更加明显
*/
// System.out.println(m.matches());
while(m.find()) {
System.out.println(m.group() + " ");
/*
* start() 返回以前匹配的初始索引。
* end() 返回最后匹配字符之后的偏移量。
* 表示获取字符串的位置,包含头不包含尾
*/
System.out.println(m.start() + "......" + m.end());
}
}
public void getMatcher() {
/*
* 用来验证String对象中的matchers就是用Pattern和Matcher对象来完成的,只不过被String的方法封装后,
* 用起来更为简单,但是String中被封装的matchers功能相对单一
*/
String str = "1367387530";
String regStr = "[1,9]\\d{4,14}";
//将规则封装成对象
Pattern p = Pattern.compile(regStr);
//让正则对象和要作用的字符串相关联,获取字符串对象
Matcher m = p.matcher(str);
//判断匹配是否成功
System.out.println(m.matches());
}
/*
* 第一个字符串是要替换的内容
* 第二个字符串是替换的规则
* 第三个字符串是用来替换的内容
*/
public void replaceAllDemo(String str,String strReg,String newStr) {
str = str.replaceAll(strReg, newStr);
System.out.println("替换以后的字符串变为 : " + str);
}
public void splitDemo(String str,String strReg) {
//切割完以后返回的是String数组
String []arr = str.split(strReg);
//查看切割以后字符串的数量
System.out.println("切割以后字符串的数量 : " + arr.length);
for(String i : arr)
System.out.print(i + "*");
System.out.println();
}
//匹配手机号
public void Tel() {
/*
* 定义规则如下:
* 手机号码只能是11位,第一位只能是1,第二位可以是3,5,7;
* 后面9位可以是0-9的任意一个数字
*/
String tel = "13254687601";
//{9}表示\\d正好出现9次
String telReg = "1[357]\\d{9}";
System.out.println("验证电话 : " + tel.matches(telReg));
}
public void QQ() {
/*
* 定义规则如下:
* 第一位不能是0,QQ号码的长度是6-15位;
* 除第一位以外的位可以是0-9的任意一个数字
*/
String qq = "1367387530";
//{5,14}表示\\d出现的次数在5-14之间
String qqReg = "[1-9]\\d{5,14}";
System.out.println("验证QQ : " + qq.matches(qqReg));
}
public void Email() {
/*
* 定义规则如下:
* 17839192987@163.com
* 如上面这种形式,@前面的位数在5-15之间,为大写字母小写字母和数字三种形式;
* @后面.前面的位数在2-3位之间,只能是qq或者163;
* .后面的为com,而且只能是com
*/
String email = "17839192987@qq.com";
String []emialReg = {"\\w{5,15}+@163.com","\\w{5,15}+@qq.com"};
boolean flag = email.matches(emialReg[0]);
//如果不是163邮箱,则继续验证是否是qq邮箱
if(flag == false)
flag = email.matches(emialReg[1]) ? true : false;
System.out.println("验证邮箱 : " + flag);
}
}
运行结果
shi
12......15
liu
24......27
zhi
31......34
dao
35......38
yao
39......42
gan
43......46
--------------------------------------
true
--------------------------------------
替换以后的字符串变为 : as##we###w######y#####ew##djhsddog#######isd#######jfksgh########adbcja##gd
--------------------------------------
替换以后的字符串变为 : as12we344w#y#ew56djhsddog#isd#jfksgh#adbcja45gd
--------------------------------------
替换以后的字符串变为 : as##fsgdkf##kdfg#dfg#sdfgd#
--------------------------------------
替换以后的字符串变为 : as#fsgdkf#kdfg#dfg#sdfgd#
--------------------------------------
替换以后的字符串变为 : asafsgdkfakdfgkdfgjsdfgdg
--------------------------------------
切割以后字符串的数量 : 3
c*abc*aa.txt*
--------------------------------------
切割以后字符串的数量 : 4
天*真*无*邪*
--------------------------------------
切割以后字符串的数量 : 4
天*真*无*邪*
--------------------------------------
切割以后字符串的数量 : 4
天*真*无*邪*
--------------------------------------
切割以后字符串的数量 : 6
sf*l*ds*gj*adodig*d*
--------------------------------------
切割以后字符串的数量 : 8
sf*l*ds*gj*dodig*da*ghd*d*
--------------------------------------
切割以后字符串的数量 : 9
********a*
--------------------------------------
切割以后字符串的数量 : 0
--------------------------------------
验证电话 : true
验证QQ : true
验证邮箱 : true