- 正则表达式概述:
首先是表达式,是一种正确的规则去进行某一种是事物的操作,用于对字符串进行操作的表达式,用于对字符串进行的操作
好处:代码更为简洁、提供了一些符号来表示一些规则,其实这个规则内部还是有具体的代码来完成对字符串操作。简单说:好像是将代码进行封装、用符号进行了替代。
弊端:正因为是符号表示的,所以要记住很多符号的使用,而且符号多了阅读性极差。
Eg:对QQ号码进行校验
要求:1、必须是5到15位。
- 必须是数字
- 0不可以开头
String qq="234234234";
String regex="[1-9][0-9]{4,14}";这就是规则,作用在字符串上的规则。
Boolean b=qq.matches(regex);
- 正则表达式常见体现:
其实就是一些常见符号的注解,必须要了解,学习正则,其实就是在学习这些符号的使用。
字符类:
[abc]:要是a或者b或者c
[^bac]:除了abc什么都行
[a-zA-Z]必须是字母
[a-b[m-p]]:a到b或者m到p
预定义字符:
.:任何字符,与行结束符可能匹配也可能不匹配
/d:数字[0-9]它是一个符号,不要以为是两个符号,不是转义。
/D:非数字[^0-9]
/s:空白字符
/S:非空白
/w:单词字符,[a-zA-Z_0-9]字符数字下划线
/W:非单词
边界匹配器:
/b:单词边界
数量词
X?:一次或者一次也没有
X*:没有或有多次
X+:必有有一次或者多次
X{n}:恰好n次
X{n,}:至少n次
X{n,m}:n到m次之间
- 正则表达式常用的功能:(重点)
- 匹配:
其实是用的就是String类中的matches方法,将正则作用到指定的字符串上判断该字符串是否符合规则,返回真假。
Eg:手机校验号码(面试题):
Public static void checkTel(){
String tel="13802920021";
Boolean b=tel.matches(regex);
String regex="1[358][0-9]{9}";
//String regex="1[358]//d{9}";
}
注意:在字符串中单/代表的是转义字符,所以为了保持原样必须把它表示原样性用//来表示。
- 切割:
其实就是使用的是String类中的split方法,将字符串按照指定的规则,变成一个字符数组,凡是参数是regex都是正则。
Eg:切割字符串
Public static void splitString(){
String str="lisi.wangwu.zhaoliu";
String regex="//.";
String[] arr=str.split(regex);
For(String s:arr){
Sop(s);
}
}
复杂切割:
Str="wwadhdhffffhehe";用叠词来切割
String regex="(.)//1+";
正则里面封转是用()来进行的,拿小括号一封装会自动分组,会有自动的编号,从1开始编号,组:是正则中封装的一种体现,不写封装都不能写编号。。
(.)(//d)//2:代表的是取第二组
Eg:((A)(B(C)))有几组?
到底有几组和每组有谁,只看左括号就行了
1:((A)(B(C)))
2:(A)
3:(B(C))
4:(C)
- 替换:
其实用的是String类中的replaceAll()方法
Eg:替换字符串:
Public static void replaceString(){
String str="abcuuufl";
Str=str.replaceAll("//d{5,}","***");
Str="acdxxxxxxshdsYYYYsdahj";叠词替换成一个字
Str=str.replaceAll("(.)//1+","$1");
Sop(str);
}
- 获取:
其实就是使用了正则表达式对象,java.util.Pattern.
- 先将正则表达式编译成Pattern对象
- 将Pattern对象将和要匹配的字符串关联,获取对应的匹配器对象。
Matcher
- 通过匹配器对象Matcher对字符串进行操作了。
Public static void getString(){
String str="da jia zhu yi le ,ming tian bu fang jia";
String regex="//b[a-z]{3}//b";/b:单词边界
Pattern p=Pattern,compile(regex);
P.mecther(str);
Matcher m=p.matcher(str);
While(m.find){
Sop(.m.group);//group方法可以返回查找到的子序列、
}
}
- 练习:
1、我我..我我我…我要要…要要学…学学学…学编编….编编….程程…程.. .程
我要学编程
public static void test_1(){
String str="";
使用替换功能
1、先将点去掉。
st=str.replaceAll("//.","");
2、将叠词替换成一个
str=str.replaceAll("(.)//1+","$1");
}
2、192.168.1.100 2.2.2.2 127.0.0.1 36.34.1.89
要求对这些ip地址进行地址段的排序
思路:
1、按照字符串的顺序比较,但是ip地址每一段位数不同。会出现错误
所以将每一段都补成三位,就可以用字符串的字典顺序比较了、
为了补位方便,按照最大的补位个数进行补位。
String ip="192.168.1.100 2.2.2.2 127.0.0.1 36.34.1.89";
每一段都补两个0,
ip=ip.replaceAll("(//d)+","00$1");
获取每一段的最后三位
ip=ip.replaceAll("0*(//d{3})","$1");
String[] ips=ip.split("" +);
TreeSet<String> ts=new TreeSet<String>();
for(String s:ips){
ts.add(s);
}
for(String s:ts){
sop(s.replaceAll("0*"));
}
3、练习三:对email地址进行校验
public static void test_3(){
String mail="abc12@sina.com";
String regex="//w+@[a-zA-Z0-9]+(//.[a-zA-Z]{2,3}){1,3}";
boolean b=mail.matches(regex);
sop(b);
}
4、网页爬虫<重点>参考:GetMainlsTest.java
其实就是一个小程序,不端的获取网络中符合规则的数据。
定义一个邮件爬虫。
public static void getMails(){
File file=new File("");
BufferedReader bufr=new BufferedReader(
new FileReader(file));
String regex="//w+@[a-zA-Z0-9]+(//.[a-zA-Z]{2,3}){1,3}";
Pattern p=Pattern.compile(regex);
String line=null;
while((line=bufr.readLine())!=null){
Matcher m=p.matcher(line);
while(m.find()){
Sop(m.group());
}
sop(line);
}}
如果是网络中:
String str_url="";
URL url=new URL(S);
- 反射技术(重要)
一个应用可以加载后期出现的类,这种情况可以使用反射技术来完成。
首先告诉类名,直接寻找类名所对应的class文件,并可以将其加载进内存,然后创建其对象,反射技术可以提高程序的扩展性,连new对象都不用了,通过反射技术可以完成对指定名称的类进行对象的创建和内容的调用,其实反射技术就是动态获取一个类,并获取类中的所有内容,简单说反射就是对类的解剖。
获取字节码文件对象的三种方式:
- 通过Object中的getClass方法获取。
Person p=new Person();
Class c1=p.getClass();
Person pp=new Person();
Class c2=pp.getClass();
Sop(c1==c2);true
因为内存只有一个通过字节码文件创建的对象,虽然是创建了两个对象,但是他们都是根据同一个字节码创建的,描述等属全部都一样,所以创建的对象也是一样的。
- 通过每一个具体数据类型具备的class静态属性就可以完成该类型的class对象的获取,这种方式:必须要明确具体的类型,比如Person;
Class c=Person.class;
Class c1=int.class;
- 通过Class类中的方法,forName就可以完成Class对象的获取,这种方式它的扩展性最强,不需要知道具体的类型、只要知道名字,就可以根绝名称就可以去加载指定的类文件,不需要具备获取class对象的类,前两种方式必须知道class类,
Class clazz=Class.forName("cn.itcast.c.bean.Person");
为什么要加包名:因为此处是字符串,所以必须要写全。
- 获取指定的字节码文件中的属性:字段:
Private static final String PERSON_STRING="cn.itcast.c.bean.person";
获取指定名称的字节码文件对象
Class clazz=Class.forName(Person_String);
通过该字节码文件对象的方法获取字节码文件中的字段:
Field[] fields=Clazz.getFields();//获取所有的字段,只能拿到公共的属性字段。
Fields=clazz.getDeclaredFields();//私有的东西都能拿到
For(Field field:fields){
Sop(field);
}
- 获取指定名称的字段:
Class clazz=Class.forName(person_string);
Field field=clazz.getField("name");
获取字段,但是对于非静态的字段,必须要有所属的对象,既然需要该类的对象,就可以通过class类中的newInstance方法来完成,该类实例的创建。
Object obj=clazz.newInstance();本身就是在调用空参数列表构造函数来完成的。
给指定字段赋值。
Field.set(obj,"lisi");
Object value=field.get(obj);
Sop(value);lisi
- 获取私有字段:
Class clazz=Class.forName(person_string);
Field field=clazz.getDeclaredField("age");
field.setAccessible(true);取消对权限的检查,暴力访问,不建议使用
Field.set(obj,69);
Object value=field.get(obj);
Object obj=clazz.newInstance();
Sop(value);
- 如果没有空参数构造函数时,要对其进行初始化该怎么办呢?
获取类中的构造函数来对指定类进行对象的初始化。
Public static void getConsDemo(){
Class clazz=Class.forName(person_String);
Constructor cons=clazz.getConstructor(String.class);
Object obj=cons.newInstance("小强");
Field field=clazz.getField("name");
Object value=field.get(obj);
}
一般被反射的类都有一个空参数构造函数
- 获取指定类中的所有方法
Public static void getMethodsDemo(){
Class clazz=Class.forName(person_String);
Mthod[] methods=clazz.getMethods();
Methods=clazz.getDeclaredMethods();获取私有的方法
For(Method method:methods){
Sop(method);
}
}
6、获取指定方法
public static void getMethodDemo(){
Class clazz=Class.forName(person_string);
Method method=clazz.getMethod("show",null);
Object obj=clazz.newInstance();
method.invoke(obj,null);//调用invoke方法。要指定参数类型,但是这里是无参数的。
}
7、获取一个带参数的方法
public static void getparamMethodDemo(){
Class clazz=Class.forName(person_string);
Method method=clazz.getMethod("paramshow",String.class,int.class);
Object obj=clazz.newInstance();
method.invoke(obj,"小明",89);
}
8、获取一个静态方法
method.invoke(nul,null);不需要参数,因为静态的都不需要对象
9、获取一个私有方法。
Method method=clazz.getDeclaredMethod("privateShow",null);
Object pbj=clazz.newInstance();
method.setAccessible(true);
method.invoke(obj,null);
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/253148.html