------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
正则表达式
1:正则表达式:符合某种规则的字符串(请注意正则表达式就是个字符串,只不过符合某种规则)由一个案例引出了正则表达式
写一个程序要求:输入一个qq号,请判断输入的这个qq号是否正确?
1)如果没有正则表达式的时候,写这个程序非常的麻烦
private static boolean checkQq(String qq) {
boolean flag = true;
// 长度
if (qq.length() >= 5 && qq.length() <= 15) {
//是否不是0开头
if(!qq.startsWith("0")){
//判断全部是数字
char[] chs = qq.toCharArray();
for(char ch : chs){
if(!(ch>='0' && ch<='9')){
flag = false;
break;
}
}
}else{
flag = false;
}
} else {
flag = false;
}
return flag;
}
2)有了正则表达式非常的简单
private static boolean checkQq2(String qq) {
//return qq.matches("[1-9][0-9]{4,14}");
return qq.matches("[1-9]\\d{4,14}");
}
2:正则表达式的规则:
A:字符
x 字符 x,任意字符代表自己本身。
\\ 反斜线字符
\r 回车
\n 换行
B:字符类
[abc] a、b 或 c,任意字符一次。
[^abc] 任何字符,除了 a、b 或 c
[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内
[0-9] 任意的数字字符一次
C:预定义字符类
. 任意的字符
\d 数字:[0-9]
\w 单词字符:[a-zA-Z_0-9]
单词字符:英文,数字,及_
D:边界匹配器
^ 行的开头
$ 行的结尾
\b 单词边界(也就是说这里出现的不能是单词字符)
abc hello world?haha
E:Greedy 数量词
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超过 m 次
F:组
捕获组可以通过从左到右计算其开括号来编号。组零始终代表整个表达式。
((A)(B(C)))
第一组:(A)(B(C))
第二组:A
第三组:B(C)
第四组:C
3:正则表达式的应用
1)String类利用正则表达式完成字符串的判断功能(校验功能)(public boolean matches(String regex))
案例1:判断字符串”qaq”中间的字符是否是元音(aeiou)
String regex = "q[aeiou]q";
String str = "qbq";
boolean flag = str.matches(regex);
System.out.println(flag);
案例2:校验电话号码
String regex = "1[35]\\d{9}";
Scanner sc =new Scanner(System.in);
System.out.println("请输入你的手机号:");
String phone = sc.nextLine();
boolean flag = phone.matches(regex);
System.out.println(flag);
案例3:校验邮箱
//String regex = "[a-zA-Z_0-9]+@[a-zA-Z_0-9]{2,8}(\\.[a-zA-Z_0-9]{2,3})+";
String regex = "\\w+@\\w{2,8}(\\.\\w{2,3})+";
Scanner sc = new Scanner(System.in);
System.out.println("请输入你的邮箱:");
String email = sc.nextLine();
boolean flag = email.matches(regex);
System.out.println(flag);
2)String类利用正则表达式完成字符串的切割功能(public String[] split(String regex))
案例1:按 "." 来切割字符串"aa.bb.cc"
String str2 = "aa.bb.cc";
String regex2 = "\\.";
String[] strArray2 = str2.split(regex2);
for (String s : strArray2) {
System.out.println(s);
}
案例2:按 所有的空格 切割字符串"-1 99 4 23"
String str4 = "-1 99 4 23";
String regex4 = " +";
String[] strArray4 = str4.split(regex4);
for (String s : strArray4) {
System.out.println(s);
}
案例3:切割计算机上的路径,把每一层路径切割出来,
比如:D:\itcast\20131130\day27\code 切成 D:itcast 20131130 day27 code
//注意java表示此路径要用这样的一个字符串:"D:\\itcast\\20131130\\day27\\code"
String str5 = "D:\\itcast\\20131130\\day27\\code";
String regex5 = "\\\\";
String[] strArray5 = str5.split(regex5);
for (String s : strArray5) {
System.out.println(s);
}
案例4:按照叠词(重复字符)切割: "sdqqfgkkkhjppppkl";(这个地方引入了组的概念)
String str = "sdqqfgkkkhjppppkl";
String regex = "(.)\\1+";
//".+" sdfgq
//"(.)\\1+" ssss
//右边出现的应该是和左边是一模一样的。
String[] strArray = str.split(regex);
for (String s : strArray) {
// sd,fg,hj,kl
System.out.println(s);
}
3)String类利用正则表达式完成字符串的替换功能
public String replaceAll(String regex,String replacement):用给定的字符串去替换字符串对象中满足正则表达式的字符。
案例1:把"sdaaafghccccjkqqqqql"替换成"sdafghcjkql",也就是叠词只留一个字符
String str2 = "sdaaafghccccjkqqqqql";
// 叠词是在同一个字符串中用\编号来引用
String regex2 = "(.)\\1+";
// 在替换方法中,第二个字符串数据中可以使用$编号的形式来引用第一个正则表达式中的组的内容
String result2 = str2.replaceAll(regex2, "$1");
System.out.println(result2);
System.out.println("--------------------");
案例2:把一个字符串
“我我....我...我.要...要要...要学....学学..学.编..编编.编.程.程.程..程” 还原成 “我要学编程”
String str = "我我....我...我.要...要要...要学....学学..学.编..编编.编.程.程.程..程";
String result = str.replaceAll("\\.", "");
String finalResult = result.replaceAll("(.)\\1+", "$1");
System.out.println(finalResult);
4)用正则表达式的包装类Pattern 和 匹配器Mathcher 结合 来完成 查找获取功能
①:记住获取模式对象和匹配器对象的这两步
// 把正则表达式编译成模式对象
Pattern p = Pattern.compile("a*b");
// 通过模式对象调用匹配方法获取到匹配器对象
Matcher m = p.matcher("aaaaab");
// 调动匹配器对象的判断功能
②:Mathcher的matches方法 和String类的matches方法差不多,只不过调用方式不一样
二者区别:
A:Mathcher的matches方法没有参数,因为在生成匹配器对象的这个过程中,
就已经把正则表达式,和需要查找的字符串传给了匹配器对象
B:String类的matches方法
String对象直接调用public boolean matches(String regex)方法,把正则表达式传进来
// 把正则表达式编译成模式对象
Pattern p = Pattern.compile("a*b");
// 通过模式对象调用匹配方法获取到匹配器对象
Matcher m = p.matcher("aaaaab");
// 调动匹配器对象的判断功能
boolean b = m.matches();
System.out.println(b);
③:Mathcher的find()方法和group()方法
find():找到字符串中匹配正则表达式的字符 返回值类型是boolean 找到了就true 找不到就false
group():获取find()找到字符
案例1:想要获取字符串中 3个字符组成的单词
// 定义规则
String regex = "\\b[a-z]{3}\\b";
String str = "da jia zhu yi le, ming tian bu fang jia, xie xie!";
// 想要获取3个字符组成的单词
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
while(m.find()){
System.out.println(m.group());
}
案例2:请把mail.txt中所有邮箱找到,并遍历出来。
A:通过字符输入流读取数据。
B:把读取到的每一行数据进行查找。
C:把查找到的数据存储到集合中。
D:遍历集合。
// 通过字符输入流读取数据。
BufferedReader br = new BufferedReader(new FileReader("mail.txt"));
// 创建一个集合
ArrayList<String> array = new ArrayList<String>();
// 定义邮箱规则
String regex = "\\w+@\\w{2,8}(\\.\\w{2,3})+";
String line = null;
while ((line = br.readLine()) != null) {
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(line);
while (m.find()) {
array.add(m.group());
}
}
// 遍历集合。
for (String s : array) {
System.out.println(s);
}
br.close();