黑马程序猿————Java基础日常笔记---反射与正則表達式

时间:2021-04-16 16:52:52

------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()); //判定此类是否是复合类,返回false System.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基础日常笔记---反射与正則表達式

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基础日常笔记---反射与正則表達式

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

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基础日常笔记---反射与正則表達式

练习:将随意一个对象中的全部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基础日常笔记---反射与正則表達式

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基础日常笔记---反射与正則表達式

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基础日常笔记---反射与正則表達式

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<len;i++){
System.out.println(Array.get(obj,i));//方法摘要 
<span style="white-space:pre"> </span>//static Object get(Object array, int index) 
<span style="white-space:pre"> </span>//返回指定数组对象中索引组件的值。 
}
}else{
System.out.println(obj);
}
}
}

总结:

基本数据类想的一维数组能够被当做是Object类型使用,不能当做Object[]类型使用,

非基本数据类型的一维数组,既能够当做Object类使用。有能够当做Object[]类型使用,

这就是Array.asList()方法处理int[]和String[]是的差异。

执行结果:

黑马程序猿————Java基础日常笔记---反射与正則表達式

1.8 反射的作用-->实现框架的功能

框架:

比方:我做房子卖给用户住,由用户自己安装门窗和空调,因此我做的放在是框架,用户须要使用我的框架。把门窗插入进我提供的框架中。

框架和工具类有差别,工具类是被用户的类调用,而框架是在调用用户提供的类

解释:

一种是你去调用别人的类。框架

一种是别人的类来调用你的类。工具类,

比方:

依照防盗门, 这个门是客户写的。做门的人须要去买锁, 锁是外面买的,

一个是开发商的房子, 一个是别人卖的锁,

可是两个的使用方法不同,

门窗被房子调用,

买回来的锁被门窗来调用。

门窗是我做的,

那么房子就是框架, 提前做好了,

你在用框架。 但 是框架在调用你的类,

锁是一个工具类。 是在调用锁。

都是别人写的。 可是使用方法不同,一个是调用别人(锁)。 一个是被别人调用(框架)。

框架要解决的核心问题:

我在写框架的时候。你这个用户可能还在读书, 还不会敲代码,我写的框架程序如何能调用到你以后写的类(门窗)呢?

由于在敲代码的时候, 无法知道要被调用的类名,所以。在程序中无法直接new某个类的实例对象。而须要用反射的反射来完毕。

2.0 正則表達式

符合一定规则的表达式,

一般操作字符串会用到字符串类中所提供的方法。 可是这样假设操作的话, 可能会比較复杂,

从而通过给字符串一定的规则,并让字符串依照这种规则运算,就会比較简便了, 

作用:用于专门操作字符串的。既便捷又简单

代码例如以下:

//对QQ号码进行校验
//要求:5~15 0不能开头,仅仅能是数字
import java.util.regex.*;
class RegexDemo
{
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<chr.length;i++){
if(!(chr[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基础日常笔记---反射与正則表達式

正則表達式经常使用构造摘要



    字符类 

    [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基础日常笔记---反射与正則表達式

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

2.1
正則表達式-分割 String split方法

import java.util.regex.*;

class SplitDemo
{
public static void main(String[] args) { splitDemo();
}
public static void splitDemo(){
String str="zhagnsan wangwu liusan";
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基础日常笔记---反射与正則表達式

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基础日常笔记---反射与正則表達式

2.2
正則表達式-获取 String replaceAll方法

需求:想把符合规则的字符串取出来, 

获取,将字符串中的符合规则的子串取出,

涉及到了几个对象

static Pattern compile(String regex) 

          将给定的正則表達式编译到模式中。

Matcher matcher(CharSequence input) 

          创建匹配给定输入与此模式的匹配器。 

 boolean find() 

          尝试查找与该模式匹配的输入序列的下一个子序列。

String group() 

          返回由曾经匹配操作所匹配的输入子序列。 

 boolean matches() 

          尝试将整个区域与模式匹配。

操作步骤:

1,将正則表達式封装成对象,

2。让正則表達式和要操作的字符串相关联

3,关联后。获取正则匹配引擎

4。通过引擎对符合规则的子串进行操作,比方取出

代码例如以下:

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基础日常笔记---反射与正則表達式

练习:

代码:

/*
需求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.*; class RegexTest
{
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<String> ts=new TreeSet<String>();
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基础日常笔记---反射与正則表達式

综上总结:

1,假设仅仅想知道该字符是否是对是错。使用匹配

2。想要将已有的字符串变成还有一个字符串,替换

3,想要依照自定的方式将字符串变成多个字符串,分割。获取规则以外的子串

4。想要拿到符合需求的字符串的子串,获取,获取符合规则的子串

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