Java基础--正则表达式、反射机制

时间:2023-02-26 12:45:07


1.正则表达式

正则表达式

  1. 正则表达式用于操作字符串数据。
  2. 通过一些特定的符号来体现的。
  3. 虽然简化了,但是阅读性差。 

2.正则表达式的构造摘要 

2.1字符

\\ 反斜线字符

\t
制表符 (‘\u0009')
\n
新行(换行)符 ('\u000A')
\r
回车符 ('\u000D')
\f
换页符 ('\u000C')
\a
报警 (bell) 符 ('\u0007')
\e

转义符 ('\u001B')


2.2字符类


[abc]
abc(简单类)
[^abc]
任何字符,除了abc(否定)
[a-zA-Z]
azAZ,两头的字母包括在内(范围)
[a-d[m-p]]
admp[a-dm-p](并集)
[a-z&&[def]]
def(交集)
[a-z&&[^bc]]
az,除了bc[ad-z](减去)
[a-z&&[^m-p]]

az,而非 mp[a-lq-z](减去)



2.3预定义字符类

.

任何字符(与结束符可能匹配也可能不匹配)

\d
数字:[0-9]
\D
非数字:[^0-9]
\s
空白字符:[ \t\n\x0B\f\r]
\S
非空白字符:[^\s]
\w
单词字符:[a-zA-Z_0-9]
\W

非单词字符:[^\w]

2.4 POSIX 字符类(仅 US-ASCII)
\p{Lower}
小写字母字符:[a-z]
\p{Upper}
大写字母字符:[A-Z]
\p{Punct}
标点符号:!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~


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

输入的结尾


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


 3.正则表达式对字符串的常见操作:
1.匹配。
 其实使用的就是String类中的matches方法。
2.切割。
 其实使用的就是String类中的split方法。  
3.替换。
 其实使用的就是String类中的replaceAll()方法。
 4.获取。

public class RegexDemo2 {

	public static void main(String[] args) {
		functionDemo_1();
		functionDemo_2();
		functionDemo_3();
		functionDemo_4();
	}

	/*
	 * 获取 将正则规则进行对象的封装。 Pattern p = Pattern.compile("a*b");
	 * //通过正则对象的matcher方法字符串相关联。获取要对字符串操作的匹配器对象Matcher . Matcher m =p.matcher("abc"); 
	 * //通过Matcher匹配器对象的方法对字符串进行操作。 
	 * boolean b =m.matches();
	 */
	public static void functionDemo_4() {

		String str = "hello! gay, are you ready?";

		String regex = "\\b[a-z]{3}\\b";// \\b单词边界

		// 1,将正则封装成对象。
		Pattern p = Pattern.compile(regex);
		// 2, 通过正则对象获取匹配器对象。
		Matcher m = p.matcher(str);

		// 使用Matcher对象的方法对字符串进行操作。
		// 既然要获取三个字母组成的单词
		// 查找。 find();
		System.out.println(str);
		while (m.find()) {
			System.out.println(m.group());// 获取匹配的子序列

			System.out.println(m.start() + ":" + m.end());
		}
	}

	// 替换
	public static void functionDemo_3() {

		String str = "zhanggggsannnnnxxxxxiaoqiangzzzzzzhaoliu";

		str = str.replaceAll("(.)\\1+", "$1");

		System.out.println(str);

		String tel = "13400001111";// 158****1111;

		tel = tel.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");

		System.out.println(tel);

	}

	// 切割 组:((A)(B(C)))
	public static void functionDemo_2() {

		String str = "zhangsanmmmmmxiaoqianxxzhaoliu";

		String[] names = str.split("(.)\\1+");// str.split("\\.");

		for (String name : names) {
			System.out.println(name);
		}

	}

	// 匹配
	public static void functionDemo_1() {
		// 匹配手机号码是否正确。
		String tel = "13005502113";

		String regex = "1[358]\\d{9}";

		boolean b = tel.matches(regex);
		System.out.println(tel + ":" + b);
	}

}

正则表达式练习:

/*
 * 1,治疗口吃:我我...我我...我我我要...要要要要...要要要要..努努努努....努努努努努.力力力力...力力力...学学编编...编编编编..编..程程...程程...程程程
 * 2,对ip地址排序。 
 * 3,对邮件地址校验。 
 */
public class RegexTest {

	public static void main(String[] args) {

		test_1();
		test_2();
		test_3();

	}

	// 对邮件地址校验。
	public static void test_3() {

		String mail = "huangc@sina.com.cn";

		String regex = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]{1,3})+";

		regex = "\\w+@\\w+(\\.\\w+)+";

		boolean b = mail.matches(regex);

		System.out.println(mail + ":" + b);

	}

	/*
	 * 1,治口吃。
	 */
	public static void test_1() {

		String str = "我我...我我...我我我要...要要要要...要要要要..努努努努....努努努努努.力力力力...力力力...学学编编...编编编编..编..程程...程程...程程程";

		// 1,将字符串中.去掉。 用替换。
		str = str.replaceAll("\\.+", "");
		System.out.println(str);

		// 2,替换叠词。
		str = str.replaceAll("(.)\\1+", "$1");
		System.out.println(str);

	}

	/*
	 * ip地址排序。
	 * 
	 * 191.168.10.03 127.127.0.1 192.192.3.3 189.70.11.55
	 */
	public static void test_2() {

		String ip_str = "192.168.10.34  127.0.0.1  3.3.3.3  105.70.11.55";

		// 1,为了让ip可以按照字符串顺序比较,只要让ip的每一段的位数相同。
		// 所以,补零,按照每一位所需做多0进行补充。每一段都加两个0.

		ip_str = ip_str.replaceAll("(\\d+)", "00$1"); // 往数字前加0
		System.out.println(ip_str);

		// 然后每一段保留数字3位。
		ip_str = ip_str.replaceAll("0*(\\d{3})", "$1");
		System.out.println(ip_str);

		// 1,将ip地址切出。
		String[] ips = ip_str.split(" +");// 一个或多个空格

		TreeSet<String> ts = new TreeSet<String>();

		for (String ip : ips) {
			ts.add(ip);
		}

		for (String ip : ts) {
			System.out.println(ip.replaceAll("0*(\\d+)", "$1"));
		}

	}

}

4.反射

4.1 反射机制

JAVA反射机制是在运行状态中,对于任意一个类 (class文件),都能够知道这个类的所有属性和方法;

 对于任意一个对象,都能够调用它的任意一个方法和属性;

 这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 

动态获取类中信息,就是java反射 。

 可以理解为对类的解剖。

4.2 获取字节码文件对象

要想要对字节码文件进行解剖,必须要有字节码文件对象.


方法1:
  1.Object类中的getClass()方法的。

  想要用这种方式,必须要明确具体的类,并创建对象,比较麻烦。


 方法2:

 2.任何数据类型都具备一个静态的属性.class来获取其对应的Class对象。

 相对简单,但是还是要明确用到类中的静态成员,但扩展性依然不足。


 方式3:

 3.只要通过给定的类的 字符串名称就可以获取该类,更为扩展。

  可是用Class类中的方法完成。

  该方法就是forName.

  这种方式只要有名称即可,更为方便,扩展性更强。 

public class ReflectDemo1 {

	public static void main(String[] args) throws ClassNotFoundException {
		getClassObject_1();
		getClassObject_2();
		getClassObject_3();

	}

	// 方式3:forName()
	public static void getClassObject_3() throws ClassNotFoundException {

		String className = "cn.itcast.bean.Person";

		Class clazz = Class.forName(className);

		System.out.println(clazz);
	}

	// 方式2:静态的属性.class

	public static void getClassObject_2() {

		Class clazz = Person.class;

		Class clazz1 = Person.class;
		System.out.println(clazz == clazz1);
	}

	// 方式1:getClass()
	public static void getClassObject_1() {

		Person p = new Person();
		Class clazz = p.getClass();

		Person p1 = new Person();
		Class clazz1 = p1.getClass();

		System.out.println(clazz == clazz1);
	}
}



4.3获取class中的构造函数Constructor

public class ReflectDemo3 {
	public static void main(String[] args) throws Exception {
		createNewObject();
		createNewObject_2();

	}

	public static void createNewObject_2() throws Exception {

		String name = "cn.itcast.exercie.Person";
		// 获取Class对象。
		Class clazz = Class.forName(name);
		// 获取到了指定的构造函数对象。
		Constructor constructor = clazz.getConstructor(String.class, int.class);

		// 通过该构造器对象的newInstance方法进行对象的初始化。
		Object obj = constructor.newInstance("wangwu", 27);

	}

	public static void createNewObject() throws Exception {

		String name = "cn.itcast.exercise.Person";
		// 获取Class对象。
		Class clazz = Class.forName(name);

		Object obj = clazz.newInstance();// 对象实例化(空参)

	}
}


4.4 获取class中的字段Field

public class ReflectDemo4 {

		public static void main(String[] args) throws Exception {
			
			getFieldDemo();
			
		}

		 // 获取字节码文件中的字段 。
		public static void getFieldDemo() throws Exception {
			
			Class clazz = Class.forName("cn.itcast.exercise.Person");
			
			Field[] fields=clazz.getFields();//获取所有公有的字段
			
			Field[] privateFields=clazz.getDeclaredFields();//获取所有私有包括共有的字段
			
			Field field = null;//clazz.getField("age");//只能获取公有的,
			
			field = clazz.getDeclaredField("age");//只获取本类,但包含私有。 
			
			//对私有字段的访问取消权限检查。暴力访问。
			field.setAccessible(true);
			
			Object obj = clazz.newInstance();
			
			field.set(obj, 99);//设置字段
			
			Object o = field.get(obj);
			
			System.out.println(o);
			

		}
		
	}

4.5 获取class中的方法Method

public class ReflectDemo5 {

		public static void main(String[] args) throws Exception {

			getMethodDemo();
			getMethodDemo_2();
			getMethodDemo_3();
			
		}
		
		

		public static void getMethodDemo_3() throws Exception {
			
			Class clazz = Class.forName("cn.itcast.bean.Person");
			
			//获取带参参数一般方法。
			
			Method method = clazz.getMethod("paramMethod", String.class,int.class);
			
			Object obj = clazz.newInstance();
			
			method.invoke(obj, "zhangqian",27);
			
			
		}

		public static void getMethodDemo_2() throws Exception {
			
			Class clazz = Class.forName("cn.itcast.exercise.Person");
			
			Method method = clazz.getMethod("show", null);//获取空参数一般方法。
			
			Constructor constructor = clazz.getConstructor(String.class,int.class);
			Object obj = constructor.newInstance("wangwu",18);
			
			method.invoke(obj, null);
			
		}

		/*
		 * 获取指定Class中的所有公共函数。
		 */
		public static void getMethodDemo() throws Exception {
			
			Class clazz = Class.forName("cn.itcast.exercise.Person");
			
			Method[] methods  = clazz.getMethods();//获取的都是公有的方法。 
			methods = clazz.getDeclaredMethods();//只获取本类中所有方法,包含私有。 
			for(Method method : methods){
				System.out.println(method);
			}
			
			
		}

	}

 4.6 反射与Properties结合

public class ReflectTest {

	public static void main(String[] args) throws Exception {

		File configFile = new File("person.properties");
		
		Properties prop = new Properties();
		FileInputStream fis = new FileInputStream(configFile);//读取文件
		
		prop.load(fis);//加载文件
		
		for(int x=0; x<prop.size(); x++){
			
			String nameP = prop.getProperty("Person"+(x+1));
			
			Class clazz = Class.forName(nameP);//获取class对象 
			
			Person p = (Person)clazz.newInstance();
			
		}
		
		fis.close();
		
	}