黑马程序员—java基础之反射与正则表达式
------- android培训、java培训、期待与您交流! ----------
凡在小事上对真理持轻率态度的人,在大事上也是不可信任的。
—--爱因斯坦
正则表达式
什么是正则表达式
正则表达式可以针对字符串定义一种格式, 可以用来检查字符串是否和这种格式匹配.
正则表达式语法
Java中的正则表达式用字符串定义:
QQ正则举例: String regex = “[1-9][0-9]{4,10}”;//1-9的数字开头,后面为0-9的数字一共5-11位;
字符:
[]代表一个字符
特殊字符:
. 任意字符
\s 空白
\d 数字
\w 字母数字下划线
数量:
+ 1次到多次
* 0次到多次
? 0次或1次
{x} 恰好x次
{x,} 至少x次
{x,y} x到y次(包含)
匹配
使用String类的matches()方法测试一个字符串是否匹配指定的正则表达式.
举例:
String regex = "[中文]";
System.out.println("中".matches(regex));//true
System.out.println("文".matches(regex));//true 下面三项全为false
System.out.println("字".matches(regex));
System.out.println("符".matches(regex));
System.out.println("中文".matches(regex));//这里可以看出,”[中文]”代表只能匹配一个.
分割
使用String类的split()方法可以把一个字符串分割成多个字符串组成的一个String[]
参数中传入一个正则表达式, 字符串中能匹配正则表达式的部分就会被作为分隔符
举例:
package com.itheima.regex;
@SuppressWarnings("unused")
public class Demo4_Split {
publicstatic void main(String[] args) {
// demo1();
demo2();
}
privatestatic void demo2() {
Strings = "abc....def..xxxx...oooo.xyz";
String[]arr = s.split("\\.+");
for(String str : arr) {
System.out.println(str);
}
}
privatestatic void demo1() {
Strings = "abc.def.xxxx.oooo.xyz";
String[]arr = s.split("\\."); //用字符串中匹配正则表达式的部分作为分隔符, 分割指定字符串
for(String str : arr) {
System.out.println(str);
}
}
}
替换
使用Stirng类的replaceAll()方法, 可以把一个字符串中匹配指定正则表达式的部分替换掉
举例:
Strings = "[abc],[def],[abc]";
//第一个参数就是一个普通的字符串, 把s中的"[abc]"替换为x.
System.out.println(s.replace("[abc]","x"));
//第一个参数是一个正则表达式, 把s中能匹配"[abc]"的部分替换为x.
System.out.println(s.replaceAll("[abc]","x"));
查找
先使用Pattern.compile()方法把一个正则表达式封装成模式对象
再调用Pattern类的matcher()方法创建一个指定字符串的匹配器(Matcher)
调用Matcher类的find()方法可以查找字符串中是否包含能匹配正则的部分.
如果find()的结果是true, 可以调用group()方法获取匹配的部分.
如果find()的结果是true, 找到一次之后再次调用find(), 会从上次找到的位置继续找.
举例:
package com.itheima.regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Demo6_Find {
publicstatic void main(String[] args) {
Strings = "我的QQ号是: 526875501, 以前使用的QQ号是: 123456, QQ客服号码是:10000";
Stringregex = "[1-9]\\d{4,10}";
Patternp = Pattern.compile(regex); //把正则表达式封装成一个模式对象
Matcherm = p.matcher(s); //用模式对象创建一个指定字符串的匹配器
while(m.find()) //如果字符串中包含能匹配正则的部分, 就返回true
System.out.println(m.group()); // 获取上一次匹配的部分
}
}
捕获组
在正则表达式中可以用小括号来定义一个组
在表达式中如果要使用小括号中匹配到的内容, 那么就可以用\1, \2, \3, \后面写几就是引用第几个小括号中的内容
如果在replaceAll()中替换时, 向替换成某个小括号中匹配的内容, 那么可以使用$1, $2, $3
举例:
package com.itheima.regex;
@SuppressWarnings("unused")
public class Demo7_Group {
publicstatic void main(String[] args) {
// demo1();
// demo2();
// demo3();
// demo4();
demo5();
Stringip = "61.54.231.9";
System.out.println(ip.replaceAll("(\\d{1,3})","00$1") // 把1-3位数字前面加上2个0, 得到: 0061.0054.00231.009
.replaceAll("0*(\\d{3})", "$1")); // 保留3位数字, 去掉前面的0, 得到: 061.054.231.009
}
privatestatic void demo5() {
//包含5连数字的手机号
Stringregex = "(1[3458](\\d)\\2{4}\\d{4})|(1[3458]\\d{4}(\\d)\\4{4})";
System.out.println("13888881234".matches(regex));
System.out.println("13999991234".matches(regex));
System.out.println("13555551234".matches(regex));
System.out.println("18600088888".matches(regex));
System.out.println("13901088888".matches(regex));
System.out.println("13900012345".matches(regex));
}
privatestatic void demo4() {
//尾号5连的手机号
Stringregex = "1[3458]\\d{4}(\\d)\\1{4}"; //第1位是1, 第2位是3456其中之一, 4个任意数字, 任意数字, 前面的数字重复出现4次
System.out.println("18600088888".matches(regex));
System.out.println("13901088888".matches(regex));
System.out.println("13902266667".matches(regex));
System.out.println("13912345678".matches(regex));
}
privatestatic void demo3() {
Strings = "我我我要要娶娶媳媳妇";
System.out.println(s.replaceAll("(.)\\1+","$1")); // "$1"代表第一个小括号中匹配到的内容.
}
privatestatic void demo2() {
//AABB 高高兴兴 快快乐乐 XXOO
Stringregex = "(.)\\1(.)\\2";
System.out.println("AABB".matches(regex));
System.out.println("高高兴兴".matches(regex));
System.out.println("快快乐乐".matches(regex));
System.out.println("XXOO".matches(regex));
System.out.println("ABAB".matches(regex));
}
privatestatic void demo1() {
//ABAB 凉快凉快 暖和暖和 学习学习
Stringregex = "(.)(.)\\1\\2"; //"\\1"代表第一个小括号中匹配到的内容,"\\2"代表第二个小括号中匹配到的内容
System.out.println("ABAB".matches(regex));
System.out.println("凉快凉快".matches(regex));
System.out.println("暖和暖和".matches(regex));
System.out.println("学习学习".matches(regex));
System.out.println("AABB".matches(regex));
}
}
正则详解
package com.itheima.regex;
@SuppressWarnings("unused")
public class Demo2_Syntax {
publicstatic void main(String[] args) {
// demo1();
// demo2();
// demo3();
// demo4();
// demo5();
// demo6();
// demo7();
// demo8();
// demo9();
// demo10();
// demo11();
// demo12();
// demo13();
// demo14();
// demo15();
// demo16();
// demo17();
// demo18();
demo19();
}
privatestatic void demo19() {
Stringregex = "[abc]{1,3}"; //1到3次
System.out.println("".matches(regex));
System.out.println("a".matches(regex));
System.out.println("aa".matches(regex));
System.out.println("aaa".matches(regex));
System.out.println("aaaa".matches(regex));
}
privatestatic void demo18() {
Stringregex = "[abc]{1,}"; //至少1次
System.out.println("".matches(regex));
System.out.println("a".matches(regex));
System.out.println("aa".matches(regex));
System.out.println("aaa".matches(regex));
System.out.println("aaaa".matches(regex));
}
privatestatic void demo17() {
Stringregex = "[abc]{2}"; //恰好2次
System.out.println("".matches(regex));
System.out.println("a".matches(regex));
System.out.println("aa".matches(regex));
System.out.println("aaa".matches(regex));
System.out.println("aaaa".matches(regex));
}
privatestatic void demo16() {
Stringregex = "[abc]+"; //任意长度的, 由abc组成的字符串. 不包含0次的.
System.out.println("".matches(regex));
System.out.println("a".matches(regex));
System.out.println("b".matches(regex));
System.out.println("c".matches(regex));
System.out.println("abc".matches(regex));
System.out.println("abcbaabcacbabcabcbabcacacabcbacbabcabcbacbabcbacbacbabcabcbacacb".matches(regex));
System.out.println("abcd".matches(regex));
}
privatestatic void demo15() {
Stringregex = "[abc]*"; //任意长度的, 由abc组成的字符串. 包含0次的.
System.out.println("".matches(regex));
System.out.println("a".matches(regex));
System.out.println("b".matches(regex));
System.out.println("c".matches(regex));
System.out.println("abc".matches(regex));
System.out.println("abcbaabcacbabcabcbabcacacabcbacbabcabcbacbabcbacbacbabcabcbacacb".matches(regex));
System.out.println("abcd".matches(regex));
}
privatestatic void demo14() {
Stringregex = "[abc]?"; //0次或1次
System.out.println("".matches(regex));
System.out.println("a".matches(regex));
System.out.println("b".matches(regex));
System.out.println("c".matches(regex));
System.out.println("aa".matches(regex));
}
privatestatic void demo13() {
Stringregex = "[0-z]"; //码表值顺序
System.out.println("a".matches(regex));
System.out.println("1".matches(regex));
System.out.println("B".matches(regex));
}
privatestatic void demo12() {
Stringregex = "\\W";
System.out.println("".matches(regex));
System.out.println("a".matches(regex));
System.out.println("A".matches(regex));
System.out.println("5".matches(regex));
System.out.println("_".matches(regex));
System.out.println("@".matches(regex));
System.out.println("aa".matches(regex));
}
privatestatic void demo11() {
Stringregex = "\\s"; //1个字符, 任意空白字符
System.out.println("".matches(regex)); //英文空格
System.out.println(" ".matches(regex)); //中文全角空格
System.out.println(" ".matches(regex)); // 1个TAB
System.out.println(" ".matches(regex)); // 4个英文空格
System.out.println("\t".matches(regex));
System.out.println("\r".matches(regex));
System.out.println("\n".matches(regex));
System.out.println("\r\n".matches(regex));
}
privatestatic void demo10() {
Stringregex = "\\d"; //1个字符, 任意数字
System.out.println("1".matches(regex));
System.out.println("7".matches(regex));
System.out.println("17".matches(regex));
}
privatestatic void demo9() {
Stringregex = "\\."; //特殊字符用\转义, Java中要用两个\\
System.out.println("a".matches(regex));
System.out.println("b".matches(regex));
System.out.println("c".matches(regex));
System.out.println("@".matches(regex));
System.out.println(".".matches(regex));
}
privatestatic void demo8() {
Stringregex = "."; //1个任意字符
System.out.println("a".matches(regex));
System.out.println("b".matches(regex));
System.out.println("c".matches(regex));
System.out.println("@".matches(regex));
System.out.println(".".matches(regex));
System.out.println("ab".matches(regex));
System.out.println("..".matches(regex));
}
privatestatic void demo7() {
Stringregex = "[a-z&&[^bcd]]"; //a-z除了bcd
System.out.println("a".matches(regex));
System.out.println("b".matches(regex));
System.out.println("c".matches(regex));
System.out.println("d".matches(regex));
System.out.println("e".matches(regex));
}
privatestatic void demo6() {
Stringregex = "[a-d&&b-e]"; //交集
System.out.println("a".matches(regex));
System.out.println("b".matches(regex));
System.out.println("c".matches(regex));
System.out.println("d".matches(regex));
System.out.println("e".matches(regex));
}
privatestatic void demo5() {
Stringregex = "[a-dm-p]"; //并集
System.out.println("a".matches(regex));
System.out.println("e".matches(regex));
System.out.println("n".matches(regex));
System.out.println("o".matches(regex));
System.out.println("q".matches(regex));
}
privatestatic void demo4() {
Stringregex = "[a-zA-Z]"; //1个字符, a-z或者A-Z, 也就是所有英文字母
System.out.println("a".matches(regex));
System.out.println("e".matches(regex));
System.out.println("z".matches(regex));
System.out.println("A".matches(regex));
System.out.println("X".matches(regex));
System.out.println("O".matches(regex));
}
privatestatic void demo3() {
Stringregex = "[^abc]"; //1个字符, 除了abc以外的任意字符
System.out.println("a".matches(regex));
System.out.println("b".matches(regex));
System.out.println("c".matches(regex));
System.out.println("d".matches(regex));
System.out.println("aa".matches(regex));
System.out.println("abc".matches(regex));
System.out.println("def".matches(regex)); // 一对中括号就代表一个字符
System.out.println("".matches(regex));
System.out.println(" ".matches(regex));
System.out.println("中".matches(regex));
System.out.println("^".matches(regex));
System.out.println("1".matches(regex));
System.out.println("97".matches(regex));
System.out.println("".matches(regex));
}
privatestatic void demo2() {
Stringregex = "a";
System.out.println("a".matches(regex));
System.out.println("".matches(regex));
}
privatestatic void demo1() {
Stringregex = "[abc]"; //定义一个正则表达式, 一个特殊的字符串. 可以匹配: 1个字符, a或b或c
System.out.println("a".matches(regex)); // 判断指定的字符串是否匹配指定的正则表达式
System.out.println("b".matches(regex));
System.out.println("c".matches(regex));
System.out.println("d".matches(regex));
System.out.println("aa".matches(regex));
System.out.println("abc".matches(regex));
}
}
反射
什么是反射
反射就是通过Class对象访问其内部的构造函数(Constructor),属性(Field), 方法(Method)
获取Class对象
Class.forName()方法可以根据一个类名获取指定类的Class对象(.class文件)
举例:
packagecom.itheima.reflect;
public class Demo2_Class {
publicstatic void main(String[] args) throws Exception {
Class<?>c = Class.forName("cn.itcast.bean.Student"); // 通过类名, 找到Student.class文件
System.out.println(c.newInstance()); // 用该文件创建一个对象
}
}
创建对象
Class类的newInstance()方法可以调用该类的无参构造函数创建对象, 如果该类没有无参构造函数则不能创建.
Class类的getConstructor()方法可以根据实参类型获取指定的构造函数对象(Constructor).
Constructor类的newInstance()方法可以传入实参创建对象.
示例:
package com.itheima.reflect;
import java.lang.reflect.Constructor;
public class Demo3_Constructor {
publicstatic void main(String[] args) throws Exception {
Class<?>clazz = Class.forName("cn.itcast.bean.Student");
Constructor<?>c = clazz.getConstructor(String.class, int.class); // 通过参数类型, 获取指定的构造函数
System.out.println(c.newInstance("张三", 21)); //调用构造函数, 传入实参, 创建对象
System.out.println(c.newInstance("李四", 22));
System.out.println(c.newInstance("王五", 20));
System.out.println(c.newInstance("赵六", 23));
}
}
字段
Class类的getField()方法可以获取当前类中可见的字段,包括从父类继承的.
Class类的getDeclaredField()方法可以获取当前中声明的所有字段,包括私有的.
如果要访问私有的字段, 需要调用setAccessible()设置访问权限
Field类的set()方法可以设置该字段的值
示例:
package com.itheima.reflect;
import java.lang.reflect.Field;
public class Demo4_Field {
public static voidmain(String[] args) throws Exception {
Class<?>clazz = Class.forName("cn.itcast.bean.Student");
Object obj =clazz.newInstance();
FieldnameField = clazz.getDeclaredField("name"); // 获取该类中声明的名为"name"的字段
nameField.setAccessible(true); //修改访问权限
nameField.set(obj,"张三"); //设置当前字段的值
FieldageField = clazz.getDeclaredField("age");
ageField.setAccessible(true);
ageField.set(obj,20);
System.out.println(obj);
}
}
方法
Class类的getMethod()方法可以获取当前类中的可见方法
Class类的getDeclaredMethod方法可以获取当前类中声明的所有方法
如果要调用私有方法, 需要调用setAccessible()设置访问权限
Method类的invoke()方法可以执行该方法
示例:
package com.itheima.reflect;
import java.lang.reflect.Method;
public class Demo5_Method {
public static voidmain(String[] args) throws Exception {
Class<?>clazz = Class.forName("cn.itcast.bean.Student");
Object obj =clazz.newInstance();
MethodsetNameMethod = clazz.getMethod("setName", String.class); // 根据方法名以及形参类型获取方法
setNameMethod.invoke(obj,"张三"); //执行方法, 传入实参
Method studyMethod= clazz.getMethod("study"); //获取当前类的一个方法, 没有任何形参的
studyMethod.invoke(obj); //执行当前类的方法, 不传入任何实参
}
}