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

 

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