java基础---反射|黑马程序员————Java基础日常笔记---反射与正则表达式

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

黑马程序员————Java基础日常笔记---反射与正则表达式

1.1反射
反射的理解和作用:
首先需要明白,用java语言编写的程序,编译后的是java文件,运行后变成字节码文件,
而编写的每个Java类看来也是一个复杂的事物中,都有自己的属性,像构造方法,成员变量,成员方法等。
就像一辆汽车,有自己的车轮,发动机,方向盘等等,
那么java类这类事物,就可以用一个类描述,通过这个类的方法就可以得到java类中定义的属性(构造方法,成员变量,成员方法等);
那么这个类就是Class类, 即字节码类。


进过理解,反射是通过Class类来实现的,通过调用Class类中的方法可以得到Java类中的成员,
而Java类的这些成员也是被封装成了一个对象, 并描述了,
因此,
反射就是把java类中的各个成分(成员变量,成员方法,构造方法)映射成相应的成分的java类。

简单的理解:
java类是一个事物,通过魔法镜(Class类)的照射(Class类中的方法),就可以得到这个java事物中的各个部分了。
其中像变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应的类的实例对象来表示的,
像Filed类,Method,Constructor,Package等等;

1.2 获取Class类对象的方式---反射的基石
方法一:Object类中的getClass()方法,而用这种方式获取, 首先需要明白具体的类和获取该类的对象。
方法二:任何的数据类型都有一个静态的属性.class,即通过类名.class,获取对应的Class类对象;
以上两种都需要明确类的对象,和类,扩展性差点;
方法三:可以通过给定的类的字符串的名称就可以获取该类, 用Class的forName(“类名”),这样更方便扩展性强;‘
代码如下:

/* Class类中: boolean isPrimitive() 判定指定的 Class 对象是否表示一个基本类型。 boolean isSynthetic() 如果此类是复合类,则返回 true,否则 false。 */ import java.lang.reflect.*; class ReflectDemo { public static void main(String[] args) throws Exception { //得到这个类的字节码的三种方式 String str="abc"; Class cls1=String.class; //类名.class Class cls2=str.getClass(); //对象名.getClass()方法 Class cls3=Class.forName("java.lang.String"); //Class.forName("java.lang.String"); System.out.println(cls1==cls2); System.out.println(cls1==cls3); System.out.println(cls1.isPrimitive()); //判定指定的 Class 对象是否表示一个基本类型。 返回false System.out.println(cls1.isSynthetic()); //判定此类是否是复合类,返回falseSystem.out.println(int.class.isPrimitive()); //返回true System.out.println(int.class == Integer.class); //返回false System.out.println(int.class == Integer.TYPE); //所以基本类型也可以写成Integer.TYPE System.out.println(int[].class.isPrimitive()); //返回false,不是原始类型,但是一个类型 System.out.println(int[].class.isArray()); //返回true ReflectPointer pt1=new ReflectPointer(3,5); //得到某个类上的某个字段 //首先需要得到这个类的字节码 Field fieldY=pt1.getClass().getField("y"); //得到成员变量,需要这个字段的名字 //filedY的值是多少?是5,错!现在只是对应到类字节码上的变量,没有对应到对象身上 System.out.println(fieldY.get(pt1)); //需要了解到底是哪个对象的值 } }

运行结果:
java基础---反射|黑马程序员————Java基础日常笔记---反射与正则表达式
文章图片

1.3 构造方法的反射应用
Constructor类代表某各类中的一个构造方法
a,得到某个类中的所有的构造方法:
Constructor[] constructor=Class.forName("java.lang.String").getConstructors();
b,得到某一个构造方法
Constructor constructor=Class.forName("java.lang.String").getConstructor(); //无参数的构造方法
Constructor constructor=Class.forName("java.lang.String").getConstructor(类.class...); //有参数的指定公共构造方法
Constructor constructor=Class.forName("java.lang.String").getDeclaredConstructor(类.class...); //有参数的指定构造方法
通过new String(new BufferString("abc")); ,用反射的方式来实现:
代码:

//new String(new StringBuffer("abc")); //用反射的思想来实现这个效果 //首先需要需要得到这个String的构造方法 String.class.getConstructor(Class...ParameterType) import java.lang.reflect.*; class ConstructorDemo { public static void main(String[] args) throws Exception { Constructor cons1=String.class.getConstructor(StringBuffer.class); //这里的StringBuffer是选择哪个构造方法//得到了这个构造方法,需要干什么, 那么只有这个类知道 //有了这个构造方法,就可以构造出一个实例对象, 通过Constructor类的方法 //newInstance(Object... initargs) 通过String.class 得到的 /* Constructor类的对象并不知道是对应的哪个构造方法 只有当运行的时候才知道对应的是哪个构造方法 而编译的时候, 是不知道用的是哪个构造方法的, 写程序的人在代码运行时才知道,所以需要强转(String) 也就是说开始编译的时候,是将Constructor constructor1=String.class.getConstructor(StringBuffer.class); 编译成二进制,没有执行这个代码, 所以不知道等号的右边是什么, 只有在运行的时候才知道具体情况是如何的, 现在是在编译阶段, 所以编译器只看变量的定义 , 不看变量的执行 */ String str = (String)cons1.newInstance(/*"abc"*/new StringBuffer("abc")); //这里的StringBuffer,是用这个StringBuffer所传的对象进去 //这里的StringBuffer必须是一致的, //类型, 和同样类型的对象 System.out.println(str.charAt(2)); } }

运行结果:

java基础---反射|黑马程序员————Java基础日常笔记---反射与正则表达式
文章图片

java基础---反射|黑马程序员————Java基础日常笔记---反射与正则表达式
文章图片

1.4 成员变量的反射
Java类上的成员变量也是用一个Field类来表示的,Field 类代表某个类中的一个成员变量
在Class类中提供了方法可以得到Field类的对象:
Field getField(String name)
返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段
Field getDeclaredField(String name)
返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。
代码如下;

/* Field getField(String name) 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段 Field getDeclaredField(String name) 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。 Object get(Object obj) 返回指定对象上此 Field 表示的字段的值。 void setAccessible(boolean flag) 将此对象的 accessible 标志设置为指示的布尔值。 */ import java.lang.reflect.*; class ReflectPointer { private int x; public int y; public ReflectPointer(int x,int y){ this.x=x; this.y=y; } }class FieldDemo1 { public static void main(String[] args) throws Exception { ReflectPointer pt1=new ReflectPointer(3,5); //得到某个类上的某个字段 //首先需要得到这个类的字节码 Field fieldY=pt1.getClass().getField("y"); //y的定义,得到成员变量,需要这个公共字段的名字 //filedY的值是多少?是5,错!现在只是对应到类字节码上的变量,没有对应到对象身上 System.out.println("pt1对象的变量y的值"+fieldY.get(pt1)); //需要了解到底是哪个对象的值Field fieldX=pt1.getClass().getDeclaredField("x"); //得到指定对象已声明字段。 fieldX.setAccessible(true); //暴力访问; System.out.println("pt1对象的变量x的值"+fieldX.get(pt1)); } }

运行结果:
java基础---反射|黑马程序员————Java基础日常笔记---反射与正则表达式
文章图片

练习:将任意一个对象中的所有String类型的成员变量所对应的字符串内容的“b”改成“a”;
代码如下:

/* 需求: 将任意一个对象中的所有String类型的成员变量所对应的字符串 内容的“b”改成“a”. Class getType() 返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型。 void set(Object obj, Object value) 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。 */import java.lang.reflect.*; //这句话一定要写,否则编译通不过。class ReflectPointer { private int x; public int y; public String str1="ball"; public String str2="basketball"; public String str3="asp"; public ReflectPointer(int x,int y){ this.x=x; this.y=y; } public String toString(){ return str1+".."+str2+"..."+str3; } }class FieldDemo3 { public static void main(String[] args) throws Exception { ReflectPointer pt1=new ReflectPointer(5,3); System.out.println("开始是:"+pt1); changeStringValue(pt1); System.out.println("字符串内容的“b”改成“a”的结果是:"+pt1); } public static void changeStringValue(Object obj) throws Exception{ //首先需要得到这个类对象中所有的String类型的变量 Field[] fields=obj.getClass().getFields(); for(Field field:fields){ if(field.getType()==String.class){//这里就判断了,只获取String类 String oldStr=(String)field.get(obj); String newStr=oldStr.replace('b','a'); //调用String replace(char oldChar, char newChar) field.set(obj,newStr); }} } }

结果:
java基础---反射|黑马程序员————Java基础日常笔记---反射与正则表达式
文章图片

1.5 成员方法的反射
Method类代表某个类中的一个成员方法,那么就可以用这个Method类的对象去调用各个对象了
得到Method类中的某个方法
Method getMethod(String name, Class... parameterTypes)
返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
举例:Method charAt=Class.forName("java.lang.String").getMethod("charAt",int.class);

Object invoke(Object obj, Object... args)
对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。

通常调用某类中的方法:
str1.charAt(1);
通过反射的方式来实现:当得到Method类对象后:
charAt.invoke(str1,1);
注意:如果传递给Method对象的invoke()方法的一个参数为Null,说明Method对象对应的是一个静态方法!!!
Object invoke(Object obj, Object... args)
对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。
第一个参数是哪个这个类字节码类的方法,
第二个参数是这个字节码类的方法中的参数(因为方法可以重载,选取哪个(参数列表)),
有多少个参数, 就写多少个class进去,ok,
代码如下:

import java.lang.reflect.*; class ReflectPointer { private int x; public int y; public String str1="ball"; public String str2="basketball"; public String str3="asp"; public ReflectPointer(int x,int y){ this.x=x; this.y=y; } public String toString(){ return str1+".."+str2+"..."+str3; } public void methodDemo()throws Exception{ //str1.charAt(1); 用反射来实现Method methodCharAt=String.class.getMethod("charAt",int.class); /* Object invoke(Object obj, Object... args) 对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。 第一个参数是哪个这个类字节码类的方法, 第二个参数是这个字节码类的方法中的参数(因为方法可以重载,选取哪个(参数列表)), 有多少个参数, 就写多少个class进去,ok, */System.out.println(methodCharAt.invoke(str1,1)); //在用这个方法去作用于某个对象, //方法类对象的方法。 } }class MethodDemo { public static void main(String[] args) throws Exception { new ReflectPointer(3,2).methodDemo(); } }

运行结果:
java基础---反射|黑马程序员————Java基础日常笔记---反射与正则表达式
文章图片

jdk1.4和jdk1.5的invoke方法的区别:
jdk1.5: Object invoke(Object obj, Object... args),可变参数
jdk1.4:Object invoke(Object obj, Object[] args) ,数组作为参数


1.6 用反射的方式执行某个类中的main方法
代码如下:

//用反射的方式来调用某个类中的main方法 import java.lang.reflect.*; class TestArguments { public static void main(String[] args){ for(String arg:args){ System.out.println(arg); } } } class mainDemo { public static void main(String[] args) throws Exception { //一般的做法: TestArguments.main(new String[]{"111","222","333"}); //这个就是用静态的方式来调用一个类的main方法, //用反射的方式来调用某个类中的main方法,开始是不清楚需要调用哪个类的 String startingClassName=args[0]; Method mainMethod=Class.forName(startingClassName).getMethod("main",String[].class); //mainMethod.invoke(null,(Object)new String[]{"111","222","333"}); //这里不把他当成是数组, 而是把它当成是三个参数 mainMethod.invoke(null,new Object[]{new String[]{"222","111","333"}}); } }


运行结果:
java基础---反射|黑马程序员————Java基础日常笔记---反射与正则表达式
文章图片



1.7数组与Object的关系及其反射类型

具有相同维度和元素类型的数组属于同一个类型,即具有相同的Class实例对象。
代码如下:

/* 具有相同的数据类型, 和相同的维度的数组, 就是同一种类型, 那么每一个数组都是一个class对象, */ import java.lang.reflect.*; import java.util.*; class ArraysDemo { public static void main(String[] args) { //int[] a1=new int[3]; int[] a1=new int[]{1,2,3}; int[] a2=new int[4]; int[][] a3=new int[2][3]; //String[] a4=new String[4]; String[] a4=new String[]{"a","v","c"}; System.out.println(a1.getClass()==a2.getClass()); //返回true //System.out.println(a1.getClass()==a3.getClass()); //返回false,维度不同 //System.out.println(a1.getClass()==a4.getClass()); //返回false数据类型不同//想得到这个对象是什么类型, System.out.println(a1.getClass().getName()); //{I,表示int类型数组//想得到数组的父类的类型 System.out.println(a1.getClass().getSuperclass().getName()); //返回的是Object类型 System.out.println(a4.getClass().getSuperclass().getName()); Object aObj1=a1; Object aObj2=a4; //Object[] aObj3=a1; //数组是Object, 但不是Object数组 Object[] aObj4=a3; //数组的数组,数组中装着Object类的对象,等效于一个数组中装着Object, Object[] aObj5=a4; //字符串数组,数组中装着Object(String), System.out.println(a1); System.out.println(a4); //打印的是数组的地址System.out.println(Arrays.asList(a1)); //整数, 转换成了数组, 但是没有转换成数据, //原因:a1是一个Object, 所以使用JDK1.5版本的,等效于一个参数,  //所以就把这个数组的地址打印了,System.out.println(Arrays.asList(a4)); //字符串来说, 是成功的转换成了list对象, //接受的是一个Object的数据, //如果是String数组传进来, 就变成list, //通过反射来得到数组的值? Object obj=null; printObject(a1); printObject("xyz"); } public static void printObject(Object obj){//给个对象,可以判断是否是数组,并打印 Class clazz=obj.getClass(); if(clazz.isArray()){//判断是否是数组类型的 int len=Array.getLength(obj); for(int i=0; i

总结:
基本数据类想的一维数组可以被当做是Object类型使用,不能当做Object[]类型使用,
非基本数据类型的一维数组,既可以当做Object类使用,有可以当做Object[]类型使用,
这就是Array.asList()方法处理int[]和String[]是的差异。
运行结果:
java基础---反射|黑马程序员————Java基础日常笔记---反射与正则表达式
文章图片

1.8 反射的作用-->实现框架的功能
框架:
比如:我做房子卖给用户住,由用户自己安装门窗和空调,因此我做的放在是框架,用户需要使用我的框架,把门窗插入进我提供的框架中,
框架和工具类有区别,工具类是被用户的类调用,而框架是在调用用户提供的类
解释:
一种是你去调用别人的类,框架
一种是别人的类来调用你的类,工具类,
比如:
按照防盗门, 这个门是客户写的,做门的人需要去买锁, 锁是外面买的,
一个是开发商的房子, 一个是别人卖的锁,
但是两个的用法不同,
门窗被房子调用,
买回来的锁被门窗来调用,
门窗是我做的,
那么房子就是框架, 提前做好了,
你在用框架, 但 是框架在调用你的类,
锁是一个工具类, 是在调用锁,
都是别人写的, 但是用法不同,一个是调用别人(锁), 一个是被别人调用(框架),
框架要解决的核心问题:

我在写框架的时候,你这个用户可能还在读书, 还不会写程序,我写的框架程序怎样能调用到你以后写的类(门窗)呢?
因为在写程序的时候, 无法知道要被调用的类名,所以,在程序中无法直接new某个类的实例对象,而需要用反射的反射来完成。


2.0 正则表达式
符合一定规则的表达式,
一般操作字符串会用到字符串类中所提供的方法, 但是这样如果操作的话, 可能会比较复杂,
从而通过给字符串一定的规则,并让字符串按照这样的规则运算,就会比较简便了,
作用:用于专门操作字符串的,既便捷又简单

代码如下:

//对QQ号码进行校验 //要求:5~15 0不能开头,只能是数字 import java.util.regex.*; classRegexDemo { public static void main(String[] args) { checkQQ_2(); } public static void checkQQ_2(){ String qq="011133333"; String regex="[1~9][0~9]{4,14}"; boolean flag=qq.matches(regex); if(flag){ System.out.println("qq:"+qq); } else System.out.println("出现非法字符......."); } public static void checkQQ_1(){ String qq="11133333"; int len=qq.length(); if(!qq.startsWith("0")){ try { long l=Long.parseLong(qq); } catch (NumberFormatException e) { System.out.println("出现非法字符......."); } } /* char[] chr=qq.toCharArray(); boolean flag=true; for(int i=0; i='0' && chr[i]<='9')) { flag = false; break; } } if(flag){ System.out.println("qq="+qq); } else System.out.println("出现非法字符"); } else{ System.out.println("不可以以0开头"); } } */ else{ System.out.println("长度错误"); } } }

运行结果:
java基础---反射|黑马程序员————Java基础日常笔记---反射与正则表达式
文章图片

正则表达式常用构造摘要

字符类
[abc]要么是a、要么是b或要么是c
[^abc] 任何字符,除了 a、b或 c(否定)
[a-zA-Z]a到 z或 A到 Z,两头的字母包括在内(范围)

预定义字符类
. 任何字符(与行结束符可能匹配也可能不匹配)
\d数字:[0-9]
\D 非数字: [^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]

Greedy 数量词
X?X,一次或一次也没有
X*X,零次或多次
X+X,一次或多次
X{n}X,恰好 n次
X{n,}X,至少 n次
X{n,m} X,至少n次,但是不超过 m次

边界匹配器
^ 行的开头
$ 行的结尾
\b 单词边界
\B 非单词边界
\A 输入的开头
\G 上一个匹配的结尾
\Z 输入的结尾,仅用于最后的结束符(如果有的话)
\z 输入的结尾

2.1 正则表达式-匹配 String matches方法
代码如下:

import java.util.regex.*; class MatchDemo { public static void main(String[] args) { Demo(); Demo1(); Demo2(); } public static void Demo(){ String str="a124"; String reg="[abc]"; //这个字符串中的第一个字符,只能是b,或者c,或者d, //而且这个字符串只能有一个字符, String reg1="[abc][a-zA-Z]"; //中间是横杠,不是波浪线 //只能是校验长度为2的字符串 String reg2="[a-zA-Z]\\d"; //在正则表达式中\d,是一个整体,并不是转移义了, String reg3="[a-zA-Z]\\d*"; String reg4="[a-zA-Z]\\d{1,}"; boolean b=str.matches(reg4); System.out.println(b); } //校验QQ号 public static void Demo1(){ String qq="012523"; String regex="[1-9]\\d{4,14}"; boolean b=qq.matches(regex); if(b){ System.out.println("qq="+qq); }else System.out.println("无效输入"); } //校验电话号码 public static void Demo2(){ String tel="13567897894"; String regex="1[368]\\d{9}"; boolean b=tel.matches(regex); if(b){ System.out.println("tel="+tel); }else System.out.println("无效输入"); } }


运行结果:
java基础---反射|黑马程序员————Java基础日常笔记---反射与正则表达式
文章图片

2.1 正则表达式-切割 String split方法


import java.util.regex.*; class SplitDemo { public static void main(String[] args) {splitDemo(); } public static void splitDemo(){ String str="zhagnsanwangwuliusan"; String str1="zhagnsan.wangwu.liusan"; String str2="C:\\abc\\d.txt"; String str3="abzzzdeccccikzzz"; String regex=" +"; //按照多个空格来切 //String regex1=" *"; String regex1="\\."; //String str1="zhagnsan.wangwu.liusan"; 按点来切 String regex2="\\\\"; //String str2="C:\\abc:\\d.txt"按\\来切 String regex3="(.)\\1+"; //按叠词切 //前一个是任意字符, 第二位在重用第一位的结果(), //想对一个规则重用的时候, 可以把这个对象封装成组, //那么这个组里面的结果就可以重新在被使用了,String[] arr=str3.split(regex3); System.out.println(arr.length); for(String s:arr){ System.out.println(s); } } }

运行结果:
java基础---反射|黑马程序员————Java基础日常笔记---反射与正则表达式
文章图片

2.2 正则表达式-匹配 String replaceAll方法

代码:

import java.util.regex.*; class ReplaceAllDemo { public static void main(String[] args) { String str="weil13926668976ty134355334uicd69896878"; //将字符串中的数字替换成### replaceAllDemo(str,"\\d{5,}","###"); //把是数字超过5个的替换成###String str1="weilxxxtyssuicdxxx"; replaceAllDemo(str1,"(.)\\1+","%%%"); } public static void replaceAllDemo(String str,String regex,String newStr){ str=str.replaceAll(regex,newStr); //将str字符串按照regex的规则替换成newStr, System.out.println(str); } }

运行结果:
java基础---反射|黑马程序员————Java基础日常笔记---反射与正则表达式
文章图片

2.2 正则表达式-获取 String replaceAll方法

需求:想把符合规则的字符串取出来,
获取,将字符串中的符合规则的子串取出,
涉及到了几个对象
static Pattern compile(String regex)
将给定的正则表达式编译到模式中。
Matcher matcher(CharSequence input)
创建匹配给定输入与此模式的匹配器。
boolean find()
尝试查找与该模式匹配的输入序列的下一个子序列。
String group()
返回由以前匹配操作所匹配的输入子序列。
boolean matches()
尝试将整个区域与模式匹配。

操作步骤:
1,将正则表达式封装成对象,
2,让正则表达式和要操作的字符串相关联
3,关联后,获取正则匹配引擎
4,通过引擎对符合规则的子串进行操作,比如取出

代码如下:
【java基础---反射|黑马程序员————Java基础日常笔记---反射与正则表达式】
import java.util.regex.*; class RegexDemo2 { public static void main(String[] args) { String str="ming tian jiu yao fang jia le,da jia"; //String str1="12324353"; String regex="\\b[a-z]{3}\\b"; //d单词边界\b, //String reg="[1-9][0-9]{4,14}"; //将规则封装成一个对象 Pattern p=Pattern.compile(regex); //Pattern p1=Pattern.compile(reg); //让正则对象和要作用的字符串相关联,获取匹配器对象 Matcher m=p.matcher(str); //关联后,获取正则匹配引擎//System.out.println(m.group()); //用于获取匹配后的结果 //但是会有异常,Group方法是去获取匹配后的结果, 但是这里还没有匹配 //所以需要先找/* boolean b=m.find(); //尝试查找与该模式匹配的输入序列的下一个子序列。 System.out.println(b); System.out.println(m.group()); */ System.out.println("matches="+m.matches()); //这个正则是作用于整个字符串, 但是只有4个字符, 返回是假, while(m.find()){//那么指针就指在了t这个位置上了, System.out.println(m.group()); System.out.println(m.start()+"......"+m.end()); //走的是数组角标,这就获取了子串的所有位置, } //Matcher m1=p1.matcher(str1); //System.out.println(m1.matches()); /* 其实String类中的matches方法,用的就是Pattern和Matcher对象来完成的, 只不过被String的方法封装后, 用起来较为简单,但是功能却是单一的, */ } }

运行结果:
java基础---反射|黑马程序员————Java基础日常笔记---反射与正则表达式
文章图片

练习:
代码:


/* 需求1:将下列字符串转成:我要学编程 到底用四种功能中的哪一个呢?或者是哪几个呢? 思路方式: 1,如果只想知道该字符是否是对是错,使用匹配 2,想要将已有的字符串变成另一个字符串,替换 3,想要按照自定的方式将字符串变成多个字符串,切割,获取规则以外的子串 4,想要拿到符合需求的字符串的子串,获取,获取符合规则的子串 需求2:将ip地址进行地址段顺序的排序 “192.79.1.234 102.34.2.34 11.11.11.11 2.2.2.3 4.5.34.112” 思路: 还按照字符串的自然顺序,只要让他们每一段都是3位即可 1,按照每一段需要的最多的0进行补齐,那么每一段就会至少保证3位, 2,将每一段只保留3位,这样,所有额ip地址都是每一段3位 需求3:对邮件进行校验*/ import java.util.regex.*; import java.util.*; classRegexTest { public static void main(String[] args) throws Exception { System.out.println("需求1..................."); test_1(); System.out.println("需求2..................."); test_2(); System.out.println("需求3..................."); test_3(); } public static void test_1(){ String str="我我我....我我......要要要...学学学学.........编编编编编编........程程程程程程......"; //首先想到需要替换 String regex="\\.+"; str=str.replaceAll(regex,""); System.out.println(str); str=str.replaceAll("(.)\\1+","$1"); System.out.println("口吃修理后:"+str); } public static void test_2(){ String ip="192.79.1.234 102.34.2.34 11.11.11.11 2.2.2.3 4.5.34.112"; ip=ip.replaceAll("(\\d+)","00$1"); System.out.println("补齐0后:"+ip); ip=ip.replaceAll("0*(\\d{3})","$1"); //表示将多余的0去除,只需要(\\d{3})这一组的数字 System.out.println("多余的0去除后:"+ip); String[] ipArrs=ip.split(" "); TreeSet ts=new TreeSet(); for(String s:ipArrs){ ts.add(s); } System.out.println("排序后:"); for(String s:ts){ System.out.println(s.replaceAll("0*(\\d+)","$1")); } } public static void test_3(){ String mail="abcef32@sina.com"; String regex="[a-zA-Z_0-9]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,3}"; //较为精确的匹配 String regex1="\\w+@\\w+(\\.\\w+){1,3}"; System.out.println("此邮件是否是合法的呢, true/false?"+mail.matches(regex1)); }}

运行结果:
java基础---反射|黑马程序员————Java基础日常笔记---反射与正则表达式
文章图片


综上总结:
1,如果只想知道该字符是否是对是错,使用匹配
2,想要将已有的字符串变成另一个字符串,替换
3,想要按照自定的方式将字符串变成多个字符串,切割,获取规则以外的子串
4,想要拿到符合需求的字符串的子串,获取,获取符合规则的子串

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------







    推荐阅读