1. 程式人生 > >黑馬程式設計師——正則表示式的總結及案例

黑馬程式設計師——正則表示式的總結及案例

基礎知識點

正則表示式
作用:用於專門操作字串
本質:是一些特定的符號來表示一些程式碼的操作,其實底層肯定還是程式碼。
好處:簡化了書寫。
弊端:符號定義越多,正則越長,閱讀性越差。
常用符號:
	字元類 
		[abc] 			a、b 或 c(簡單類) 
		[^abc] 			任何字元,除了 a、b 或 c(否定) 
		[a-zA-Z] 		a 到 z 或 A 到 Z,兩頭的字母包括在內(範圍) 
		[a-d[m-p]] 	a 到 d 或 m 到 p:[a-dm-p](並集) 
		[a-z&&[def]] 	d、e 或 f(交集) 
		[a-z&&[^bc]] 	a 到 z,除了 b 和 c:[ad-z](減去) 
		[a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](減去) 
	預定義字元類 
		. 任何字元(與行結束符可能匹配也可能不匹配) 
		\d 數字:			[0-9] 
		\D 非數字: 		[^0-9] 
		\s 空白字元:		[ \t\n\x0B\f\r] 
		\S 非空白字元:	[^\s] 
		\w 單詞字元:		[a-zA-Z_0-9] 
		\W 非單詞字元:	[^\w] 
	邊界匹配器 
		^ 		行的開頭 
		$ 		行的結尾 
		\b 	單詞邊界 
		\B 	非單詞邊界 
	Greedy 數量詞 
		X? 		X,一次或一次也沒有 
		X* 		X,零次或多次 
		X+ 		X,一次或多次 
		X{n} 	X,恰好 n 次 
		X{n,} 	X,至少 n 次 
		X{n,m} X,至少 n 次,但是不超過 m 次 
組的封裝和捕獲
	可以將規則封裝成一個組。用()完成。組的出現都有編號,從1開始。
	想要使用已有的組可以通過  \n(n就是組的編號)的形式來獲取。
	如:用疊詞切割字串
		String line = "abadddddefdggdgdfffdegbd";
		String regex = "(.)\\1+";
		在表示式 ((A)(B(C))) 中,存在四個這樣的組: 通過從左到右計算其開括號來編號
		組1     ((A)(B(C))) 
		組2     \A 
		組3     (B(C)) 
		組4     (C) 
		組零始終代表整個表示式。
		組的引用:使用$n來引用組,一般用在替換操作中
		替換:String replaceAll(regex,str);如果regex中有定義組,可以在第二引數中通過$符號
		獲取正則表示式中的已有的組。
		如:把一個字串中的疊詞替換成一個字元
		String line = "abadddddefdggdgdfffdegbd";
		line.replaceAll("(.)\\1+","$1");即:用組1中的內容替換滿足表示式規則的內容
1.匹配
	String 類的mathes方法		public boolean matches(String regex)
	用規則匹配整個字串,只要有一處不符合規則,就匹配結束,返回false。
		對QQ號碼進行校驗要求:5~15  0不能開頭,只能是數字
		String regex = "[1-9]\\d{4,14}";
		匹配手機號段只有 13xxx 15xxx 18xxxx
		String telReg = "1[358]\\d{9}";
2.擷取
	String類的split功能		public String[] split(String regex)
		按照疊詞完成切割
		splitDemo("erkktyqqquizzzzzo","(.)\\1+");
		按目錄切割
		splitDemo("c:\\abc\\a.txt","\\\\");
3.替換
	String類的replaceAll功能		public String replaceAll(String regex,String str)
	注意:此方法是得到了一個新的字串,原字串的內容併為發生變化。當然可以重新賦值給原串。
	String replaceAll(regex,str);如果regex中有定義組,可以在第二引數中通過$符號
		將疊詞替換成#
		replaceAll("(.)\\1+","#");
		將疊詞替換成單個字元
		replaceAll("(.)\\1+","$1");
4.獲取
	如:獲取一段字串中符合規則的資料,獲取3個字元的單詞
	String str = "ming tian jiu yao fang jia le ,da jia。";
	String reg = "\\b[a-z]{3}\\b";
	使用正則表示式的特有功能,步驟:
		A:將正則表示式封裝成物件
			檢視API可以發現正則表示式的描述是在Pattern類中,此類是正則表示式的編譯表示形式
			Pattern p = Pattern.compile(reg);
		B:讓正則物件和要操作的字串相關聯,獲取匹配器物件
			Matcher m = p.matcher(str);
		C:通過匹配器物件的方法對符合規則的子串進行操作,如查詢和獲取
			while(m.find()){
				System.out.println(m.group());
				System.out.println(m.start()+"...."+m.end());
			}
			其實String類的matches方法,用的就是Pattern和Matcher物件來完成的
			只不過被String的方法封裝後用起來較為簡單,但是功能比較單一。
			m.matches();//這裡匹配的是符合規則的子串,如果是String的方法,匹配的這是整個字串。
			
到底用四種功能中的哪一個呢?或者哪幾個呢?
	思路方式:
	1,如果只想知道該字元是否對是錯,使用匹配。
	2,想要將已有的字串變成另一個字串,替換。
	3,想要按照自定的方式將字串變成多個字串。切割。獲取規則以外的子串。
	4,想要拿到符合需求的字串子串,獲取。獲取符合規則的子串。
拓展案例
/*
正則表示式的應用例項
1.處理"我我...我我...我要..要要...要要...學學學....學學...編編編...程式設計..程.程程...程...程"
2.192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30	將ip地址進行地址段順序的排序。
*/
import java.util.Arrays;
class ReplaceDemo{
	public static void main(String[] args){
		//測試功能
		strReg();
		
		ipReg();
	}
	public static void strReg(){
		//定義字串
		String line = "我我...我我...我要..要要...要要...學學學....學學...編編編...程式設計..程.程程...程...程";
		/*
			分析:
				使用字元創的替換功能,先把...去掉,然後在把疊詞替換為一個字元
		*/
		//把...替換為空
		line=line.replaceAll("\\.+","");
		//把疊詞替換為一個字元
		line=line.replaceAll("(.)\\1+","$1");
		//輸出結果
		System.out.println(line);
	}
	public static void ipReg(){
		//定義字串
		String line = "192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30";
		/*
			分析:
				按地址段排序其實就是自然排序,但有點小問題
				2.2.2.2肯定是在102.49....前面的,但直接排序肯定就排到後面去了
				如果變成002.002....就好了
				我們首先把位數最低的數變為3位數(用0補),然後再去掉多餘的0,排序後再去掉首位的0
		*/
		//用0把數值補位
		line = line.replaceAll("(\\d+)","00$1");
		//把多餘3位的數變為3位數
		line = line.replaceAll("0*(\\d{3})","$1");
		//用空格分隔資料
		String[] strs = line.split(" ");
		//利用陣列的工具類排序
		Arrays.sort(strs);
		//排序後遍歷陣列並把首位的0去掉後輸出
		for(String s:strs){
			System.out.println(s.replaceAll("0*(\\d+)","$1"));
		}
	}
}