Java中的正则

今天带大家了解一下Java当中的正则,依旧采用我自己 “”学习一个知识点的四部曲!“”

学习一个知识点的四部曲!
1.什么是它(正则)?

2.用它(正则)有什么好处? (这里得抛砖引玉,先讲没有它会出现什么问题,有了它解决了什么问题)
                                          突然想到了,先抑后扬,也叫欲扬先抑这种修辞手法

3.它主要包含哪些知识点(列出大纲)?

4.怎么使用它?

一:什么是它(正则)?

计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本
Regular Expression,在代码中常简写为regex、regexp或RE

 

二:用它(正则)有什么好处?
2.1没他时

例子:可能你在前端验证个邮箱,都得写满大屏幕的 if 代码,有了正则之后,轻松搞定
 

2.2有他时
上述的问题,根本就不是问题,当然正则不止止这么一点功能,上面只是举一个例子
 正则的作用主要是用来:查找,替换,匹配

三:它主要包含哪些知识点(列出大纲)?
       3.1 元字符,量词,方括号

       3.2 介绍下Java中的正则对应的类 (Pattern 和 Matcher) 及其常用方法

       3.3 String类中涉及正则的几个方法

 四:怎么使用它?
        关于怎么使用它,其实就是把上面的含义都搞懂,把下面的练习都敲一遍就基本上入门了



量词:


3.1.1元字符案列

package 字符串.原字符;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 正则的作用: 查找,替换,匹配
 * 		           仔细一察觉,其实工作中经常用: 查找(Ctrl+F),替换(replace),搜索某些文件会用*匹配
 * 
 * 演示一下: 元字符 和 量词的用法
 * @author wzj
 *
 */
public class Demo {

	public static void main(String[] args) {
		/**
		 * 元字符:只能匹配单个字符
		 * 	. :表示任意的单个字符
		 *	/d:digits(数字),匹配0~9中任意一个字符
		 *	/s:space(空格), 匹配所有空白字符:如空格,制表符(\t),换行符,回车符等
		 *	/w:word(单词) a~zA~Z,0~9,_
		 *
		 *	/D,/S,/W 大写的都是表示非
		 *  例子: /D: 匹配非数字
		 *
		 *
		 * 量词: 问嘉兴, 是表示前面这个字符的次数,例子: a?,说明可以匹配 "空字符串" 和 "一个a的"的字符串
		 * 	? : 0次或1次
		 * 	+ : 1次或多次
		 *  * : 0次或多次
		 *  这里可以画个三角形!
		 */
		//Pattern对象是正则表达式编译完后在内存中的表现形式!!
		Pattern p = Pattern.compile("\\d");
		Matcher m = p.matcher("12");//只能匹配单个数字
		System.out.println(m.matches());//fasle
		
		//如果我想表示1个或多个数字呢?就得用量词: ? + * (问嘉兴)
		boolean b2 = Pattern.compile("\\d+").matcher("2232323323").matches();
		System.out.println(b2);//true,这样的话就能匹配多个数字,这个正则除了出现数字,不能出现其他的
		
		//如果只使用一次正则,就用这种方式
		boolean b3 = Pattern.matches(".", "我的");
		System.out.println(b3);//false, 只能匹配任意单个字符
		
		boolean b4 = Pattern.matches(".*", "有点帅");
		System.out.println(b4);//true
		
		boolean b5 = Pattern.matches("ab?", "");
		System.out.println(b5);//false, 注意:量词只是匹配前一个字符的个数,这里也就是b的次数
		
		//如果想将ab表示成一个整体,得用()括起来
		boolean b6 = Pattern.matches("(ab)?", "");
		System.out.println(b6);//true,因为?代表: 0次或1次
		
		boolean b7 = Pattern.matches("\\w", "Z");
		System.out.println(b7); //true,因为\w匹配: a~z,A~Z(字母),0~9(数字),_(下划线)
		
		boolean b8 = Pattern.matches("\\D", "Z");
		System.out.println(b8);//true,因为\\D,匹配非数字
		
		System.out.println(Pattern.matches(".", " ")); //. 可以匹配空格
	}
}

3.1.2 量词案列

package 字符串.原字符;

import java.util.regex.Pattern;

/**
 * 量词的用法:
 * 	?: 表示前面字符的0次或1次
 *  +: 表示前面字符的1次或多次
 *  *: 表示前面字符的0次或多次
 *  帅{x},匹配包含x个“帅”的字符串
 *  帅{x,y}: 匹配x或者y个“帅”的字符串
 *  帅{x,}: 匹配至少x个“帅”的字符串
 *  帅$: 匹配任何结尾为“帅”的字符串,只能匹配单个字符!!
 *  ^帅: 匹配任何开头为“帅”的字符串,只能匹配单个字符!!
 *  
 *  注意事项: 注意除了使用量词,不然只能匹配单个字符!!!
 *  可能没有全部列全,但常见的就这些,用到频率多的,可以以后自己再补充!!
 * @author wzj
 *
 */
public class Demo3 {

	public static void main(String[] args) {
		
		boolean b = Pattern.matches("我是大帅{1}比", "我是大帅比");
		System.out.println(b);//true
		
		//固定每天帅一次
		boolean b2 = Pattern.matches("我是大帅{1}比", "我是大帅帅比");
		System.out.println(b2);//false
		
		//帅一次或者两次
		boolean b3 = Pattern.matches("我是大帅{1,2}比", "我是大帅帅比");
		System.out.println(b3);//true
		
		//需求:至少帅两次
		boolean b4 = Pattern.matches("我是大帅{2,}比", "我是大帅帅比");
		System.out.println(b4);//true
		
		boolean b5 = Pattern.matches("帅$", "有点帅");
		System.out.println(b5);//false: 注意除了使用量词,不然只能匹配单个字符!!!
		
//		boolean b6 = Pattern.matches("*帅$", "有点帅");
//		System.out.println(b6); //这个会报错,我们说了量词,是匹配前一个字符的次数,而这个*前面没有字符!!所以报错
		
		
		boolean b7 = Pattern.matches("[^x00-xff]*帅$", "有点帅");
		System.out.println(b7);//true, [^x00-xff]:是匹配中文的正则
		
//		boolean b8 = Pattern.matches("[^x00-xff]", "d"); //false
		boolean b8 = Pattern.matches("[^x00-xff]", "我的");
		System.out.println(b8);//false, 也是只能表示单个字符!!!
		
		boolean b9 = Pattern.matches(".*帅$", "有点帅");
		System.out.println(b9);//true, .代表任意单个字符!!
	}
}

3.1.3 方括号 

package 字符串.原字符;

import java.util.regex.Pattern;

/**
 * 方括号:
 * 	[abc]: 表示枚举,表示a,b,c任意一个字符
 *  [^abc]: 表示非a,b,c的任意字符
 *  [0-9]: 表示0~9之间的任意字符
 *  [a-z]: 表示a~z之间的任意字符
 *  [A-Z]: 同理
 *  [red|blue|green]:查找任意指定的选项,和[abc]类似!
 * 	
 * @author wzj
 *
 */
public class Demo2 {

	public static void main(String[] args) {
		
		boolean b = Pattern.matches("[abc]", "a");
		System.out.println(b);//true, 表示只要满足a,b,c中任意一个字符就行!
		
		boolean b2 = Pattern.matches("[^abc]", "de");
		System.out.println(b2);//false, 只能满足非a,b,c的 “单个” 字符, 要想满足多个得用量词!!
		
		boolean b3 = Pattern.matches("[^abc]+", "de");
		System.out.println(b3);//true
		
		boolean b4 = Pattern.matches("[^abc]+", "ad");
		System.out.println(b4);//false, 这个+量词,把前面[]中看成了一个整体,要么存在单个非a,b,c  要么多个!!
		
		boolean b5 = Pattern.matches("[0-9]", "55");
		System.out.println(b5);//false, 注意还是只能匹配单个字符!!!
		
		boolean b6 = Pattern.matches("[a-z]", "ab");
		System.out.println(b6);//false,还是只能匹配单个字符,匹配多个得用量词: ? + *
		
		boolean b7 = Pattern.matches("[苹果|橘子|香蕉]", "橘子");
		System.out.println(b7);//fasle, 注意:只能匹配单个字符!!
		
		boolean b8 = Pattern.matches("(苹果|橘子|香蕉)", "橘子");
		System.out.println(b8);//true, 使用()才是可以的 
		
		boolean b9 = Pattern.matches("[苹果|橘子|香蕉]", "橘");
		System.out.println(b9);//true
	}
}

 

 3.2 介绍下Java中的正则对应的类 (Pattern 和 Matcher) 及其常用方法

3.2.1

package 字符串.原字符;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/*
 * 介绍一下Java中的正则表达式!!
 * Pattern:模式
 * Matches:匹配器
 */
public class Demo4 {
	public static void main(String[] args) {
		//Java中的正则,提供了Pattern和
		
		//第一种写法: Pattern对象是正则表达式编译完后,在内存中的表现形式!!
		Pattern p = Pattern.compile("^H\\d{2,}\\w{3}P$");
		Matcher m = p.matcher("H123abcP");
		System.out.println(m.matches());//true
		Matcher m2 = m.reset("H123abcPW");//rest方法:可以将现有的Matcher对象应用于一个新的字符序列!
		System.out.println(m2.matches());//false
		
		//第二种写法:可以使用链式编程的写法
		boolean b = Pattern.compile("^H\\d{2,}\\w{3}P$").matcher("H123abcP").matches();
		System.out.println(b);//true
		
		//第三种写法: 如果某个正则表达式只用一次,那么直接使用Pattern类中matches()静态方法
		boolean b2 = Pattern.matches("^H\\d{2,}\\w{3}P$", "H123abcP");
		System.out.println(b2);//true
		
		//第四种写法
		System.out.println("hello".matches("\\w+"));//true
	}
}

3.2.2

package 字符串.原字符;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 	介绍Matcher类中的一些常用方法
 * @author wzj
 *
 */
public class Demo6 {
	public static void main(String[] args) {
		/**
		 * 	介绍一下matches方法和find方法
		 * 		matches:是全部匹配,字符串要完全对应正则的规则
		 * 		find:是部分匹配 ,字符串中的子串满足就行,全部满足还不行!!
		 */
		Pattern p1 = Pattern.compile("\\d");
		Matcher m1 = p1.matcher("1");
		System.out.println(m1.matches());//true :全部匹配: 跟equals方法作用类似
		System.out.println(m1.find());//false 	:find方法是部分匹配,全部匹配还不行!!
		
		
		Pattern p2 = Pattern.compile("\\d");
		Matcher m2 = p2.matcher("12");
		System.out.println(m2.matches());//false: 没有完全匹配,因为\\d只表示任意单个数字,而字符串是两个
		System.out.println(m2.find());//true: 部分匹配!
		
		
		Matcher matcher = Pattern.compile("\\w").matcher("Java is very easy!");
		while(matcher.find()) {//find():判断目标字符串中是否包含与Pattern匹配的子串
			System.out.print(matcher.group());//返回上一次和Pattern匹配的子串: 可以看出一般和find()一起使用,直接使用会报错
		}
		
		//start和end方法主要用于确定子串在目标字符串中的位置
		//创建一个Pattern对象,并用他建立一个Matcher对象
		String destStr = "Java is Very easy!";
		System.out.println("目标字符串:"+ destStr);
		Matcher matcher2 = Pattern.compile("\\w+").matcher(destStr.trim()); //遇到空格就会结束
		
		while(matcher2.find()) 
		{
			System.out.println(matcher2.group()+"\t子字符串的起始位置:"+matcher2.start()+"\t子串的结束位置:"+matcher2.end());
		}
		
	}
}

3.3 String类中涉及正则的几个方法

package 字符串.原字符;

import java.util.Arrays;

/***
 * String类中,涉及到正则的几个方法
 * 
 * boolean matches(String regex); 判断该字符串是否匹配正则
 * String replaceAll(String regex,String replacement);将字符串中匹配正则的子串替换后返回!!
 * String replaceFirst(String regex,String replacement);将字符串中匹配正则的“首个子串”替换后返回!!
 * String[] split(String regex); 根据正则拆分字符串,得到一个字符串数组!
 * @author wzj
 *
 */
public class Demo5 {
	public static void main(String[] args) {
		//1.matches用法!!
//		testMatches();
		//2.replaceAll用法!!
//		testReplaceAll();用法!!
		//3.replaceFirst
//		testReplaceFirst();
		//4.split();用法!!
		testSplit();
	}

	private static void testSplit() {
		String str = "hello , java";
		String[] split = str.split(",");
		System.out.println(Arrays.toString(split));
	}

	private static void testReplaceFirst() {
		String str = "hello , java";
		System.out.println(str.replaceFirst("\\w*", "♠"));//♠ , java:*遇到空格就停了
	}

	private static void testReplaceAll() {
		String str = "我12爱的12我的12国家";
		String newStr = str.replaceAll("\\d", "A");//将数字替换成A
		System.out.println(newStr);
	}

	private static void testMatches() {
		String str = "Hello World";
		System.out.println(str.matches("^H"));//false,除了使用量词,只能匹配单个字符!!
		System.out.println(str.matches("^H\\w*"));//false, \w遇到空格就没了
		System.out.println(str.matches("^H\\w*\\s\\w*"));//true
	}
}

练习:

package 字符串.练习;

import java.util.regex.Pattern;

//https://blog.csdn.net/qian_youyou/article/details/79121916
public class Demo1 {

	public static void main(String[] args) {
		
		//1.匹配整数的正则: 负整数,正整数,0
		boolean b = Pattern.matches("\\d+", "0");
		System.out.println(b);//这里的正则是可以将0 和 正整数搞定
		
		
		boolean b2 = Pattern.matches("-?\\d+", "-12");
		System.out.println(b2);// 需要让-可有可无, 所以用?搞定
		
		
		//2.匹配非负整数的正则: 非负整数: 0 和 正整数!
		boolean b3 = Pattern.matches("\\d+", "-1");
		System.out.println(b3);
		
		//3.匹配非正整数: 0 和 负整数
		boolean b4 = Pattern.matches("[-\\d+|0]", "-1545");
		System.out.println(b4);//fasle:[]里面只能匹配单个字符,所以用量词(?+*)作用不大!!
		
		boolean b5 = Pattern.matches("[-\\d|0]", "-");
		System.out.println(b5);//true: []:只能匹配单个字符: -, 多一个\\d就不匹配!!!
		
		boolean b5_2 = Pattern.matches("[-\\d|0]", "-1");
		System.out.println(b5_2);//fasle: 因为[]只能匹配单个字,- 和 1 是两个字符,所以不匹配!!!
		
		boolean b6 = Pattern.matches("[我的|你]", "我的");
		System.out.println(b6);//false: []里面只能匹配单个字符,所以用量词(?+*)作用不大!!

		boolean b7 = Pattern.matches("(我的|你)", "我的");
		System.out.println(b7);//true:
		
		boolean b8 = Pattern.matches("(0|-\\d+)", "-65454");
		System.out.println(b8);//ture: 表示0 或者 负整数
	}
}
package 字符串.练习;

import java.util.regex.Pattern;

public class Demo2 {

	public static void main(String[] args) {
		//1.长度为8-10的用户密码(以字母开头、数字、下划线)
		boolean b = Pattern.matches("^[A-z]\\w{7,10}", "Z1272sdsd");
		System.out.println(b);//true: [A-z]表示[a-zA-Z]中任意单个字符!!
		
		
		//2.验证输入只能是汉字
		boolean b2 = Pattern.matches("^[\\u4e00-\\u9fa5]{1,}$", "我");
		System.out.println(b2);//true: 至少匹配一个汉字{1,}等价于+,没看u4e00是什么鬼
		
		
		//3.电子邮箱验证 itcast_wzj,[email protected], [email protected],可以满足
		boolean b3 = Pattern.matches("^\\w{7,10}@\\w{2,3}.(com|cn)", "[email protected]");
		System.out.println(b3);
		
//		^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
		
		boolean b4 = Pattern.matches("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$", "[email protected]");
		System.out.println(b4);
		
		
		System.out.println(Pattern.matches("([-+.]\\w+)*", ""));//true: 这个整可以是0 或者 是多个
		System.out.println(Pattern.matches("([-+.]\\w+)*", "-dd-dd"));//true
		System.out.println(Pattern.matches("([-+.]\\w+)*", "-dd-d"));//true??????????? //TODO
		
		
		/**
		 * 这个正则挺好玩的
		 * 	1.先看圆括号里面的: [-+.]\\w+ 表示从-+.任意单个字符, 而\\w+ 表示一个或多个
		 * 		例子: 满足的字符串: -d 或 -ddd
		 *  2.然后看()*,圆括号把他们当成了一个整体, *表示0或多个
		 *  	表示多个的例子:  -d-d-d 或  -ddd-ddd-ddd
		 *  	表示多个的例子:  空字符串即可满足!!
		 */
	}
}

最后想说一下,学完之后找几个题目练练手,不然不知道它的强大之处,正则其实是挺重要的,不要以为我验证一个邮箱,去网上一搜一大把,但有时候正则可以把你处理一些特殊的字符串需求,可以省了很多的代码,我在公司就见过别人不用正则写的一大把逻辑且繁琐才解决问题,用了正则又方便,又简洁,而且正则在java中会用到,JS中也会用到,linux下也会用到,就平时在eclipse中查找的时候,也会用到,把它学会何乐而不为呢?
疑问:System.out.println(Pattern.matches("([-+.]\\w+)*", "-dd-d"));//true 这个为什么是true啊??
看到时候回过头来,能不能解决!!

System.out.println(Pattern.matches("(-\\w+)*", "-dd-d"));
		/**
		 * 	我知道为什么是true了,因为多了个+的原因
		          是把括号中看成一个整体
		 *       	第一次. -\\w+: 可能是-dd 
		 *       	第二次. -\\w+: 可能是-d
		 *          	然后*代表 0次 或 多次
		 *          
		 *          	之前的理解是先固定死()中的内容,然后看* :就是说假如()里是 -a, 然后我再*,所以我就认为,要么-a不出现,要么就是-a-a这样的规律 出现!!
		 *          	现在的理解就是:()中表达式能够出现几次!!!
		 */				
		System.out.println(Pattern.matches("(-\\w)*", "-dd-d"));//fasle

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章